gpt4 book ai didi

java - 使用 Java Card 钱包

转载 作者:搜寻专家 更新时间:2023-11-01 02:09:25 29 4
gpt4 key购买 nike

我是 java card 初学者,从示例中复制了下面的代码。不知何故,我已经能够了解部分代码的工作原理。但是还是对下面的内容感到困惑。

.ownerpin 的工作方式以及设置 pin 的方式和时间.如何使贷记和借记工作

我了解平衡是如何工作的,而且这方面还不错。下面是代码

钱包.java

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package classicapplet1;

import javacard.framework.APDU;
import javacard.framework.Applet;
import javacard.framework.ISO7816;
import javacard.framework.ISOException;
import javacard.framework.OwnerPIN;

public class Wallet extends Applet {

/* constants declaration */
// code of CLA byte in the command APDU header
final static byte Wallet_CLA = (byte) 0x80;
// codes of INS byte in the command APDU header
final static byte VERIFY = (byte) 0x20;
final static byte CREDIT = (byte) 0x30;
final static byte DEBIT = (byte) 0x40;
final static byte GET_BALANCE = (byte) 0x50;
// maximum balance
final static short MAX_BALANCE = 0x7FFF;
// maximum transaction amount
final static byte MAX_TRANSACTION_AMOUNT = 127;
// maximum number of incorrect tries before the
// PIN is blocked
final static byte PIN_TRY_LIMIT = (byte) 0x03;
// maximum size PIN
final static byte MAX_PIN_SIZE = (byte) 0x08;
// signal that the PIN verification failed
final static short SW_VERIFICATION_FAILED = 0x6300;
// signal the the PIN validation is required
// for a credit or a debit transaction
final static short SW_PIN_VERIFICATION_REQUIRED = 0x6301;
// signal invalid transaction amount
// amount > MAX_TRANSACTION_AMOUNT or amount < 0
final static short SW_INVALID_TRANSACTION_AMOUNT = 0x6A83;
// signal that the balance exceed the maximum
final static short SW_EXCEED_MAXIMUM_BALANCE = 0x6A84;
// signal the the balance becomes negative
final static short SW_NEGATIVE_BALANCE = 0x6A85;

/* instance variables declaration */
OwnerPIN pin;
short balance;

private Wallet(byte[] bArray, short bOffset, byte bLength) {

// It is good programming practice to allocate
// all the memory that an applet needs during
// its lifetime inside the constructor
pin = new OwnerPIN(PIN_TRY_LIMIT, MAX_PIN_SIZE);

byte iLen = bArray[bOffset]; // aid length
bOffset = (short) (bOffset + iLen + 1);
byte cLen = bArray[bOffset]; // info length
bOffset = (short) (bOffset + cLen + 1);
byte aLen = bArray[bOffset]; // applet data length

// The installation parameters contain the PIN
// initialization value
pin.update(bArray, (short) (bOffset + 1), aLen);
register();

} // end of the constructor

public static void install(byte[] bArray, short bOffset, byte bLength) {
// create a Wallet applet instance
new Wallet(bArray, bOffset, bLength);
} // end of install method

public boolean select() {

// The applet declines to be selected
// if the pin is blocked.
if (pin.getTriesRemaining() == 0) {
return false;
}

return true;

}// end of select method

public void deselect() {

// reset the pin value
pin.reset();

}

public void process(APDU apdu) {

// APDU object carries a byte array (buffer) to
// transfer incoming and outgoing APDU header
// and data bytes between card and CAD

// At this point, only the first header bytes
// [CLA, INS, P1, P2, P3] are available in
// the APDU buffer.
// The interface javacard.framework.ISO7816
// declares constants to denote the offset of
// these bytes in the APDU buffer

byte[] buffer = apdu.getBuffer();
// check SELECT APDU command

if (apdu.isISOInterindustryCLA()) {
if (buffer[ISO7816.OFFSET_INS] == (byte) (0xA4)) {
return;
}
ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
}

// verify the reset of commands have the
// correct CLA byte, which specifies the
// command structure
if (buffer[ISO7816.OFFSET_CLA] != Wallet_CLA) {
ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
}

switch (buffer[ISO7816.OFFSET_INS]) {
case GET_BALANCE:
getBalance(apdu);
return;
case DEBIT:
debit(apdu);
return;
case CREDIT:
credit(apdu);
return;
case VERIFY:
verify(apdu);
return;
default:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}

} // end of process method

private void credit(APDU apdu) {

// access authentication
if (!pin.isValidated()) {
ISOException.throwIt(SW_PIN_VERIFICATION_REQUIRED);
}

byte[] buffer = apdu.getBuffer();

// Lc byte denotes the number of bytes in the
// data field of the command APDU
byte numBytes = buffer[ISO7816.OFFSET_LC];

// indicate that this APDU has incoming data
// and receive data starting from the offset
// ISO7816.OFFSET_CDATA following the 5 header
// bytes.
byte byteRead = (byte) (apdu.setIncomingAndReceive());

// it is an error if the number of data bytes
// read does not match the number in Lc byte
if ((numBytes != 1) || (byteRead != 1)) {
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
}

// get the credit amount
byte creditAmount = buffer[ISO7816.OFFSET_CDATA];

// check the credit amount
if ((creditAmount > MAX_TRANSACTION_AMOUNT) || (creditAmount < 0)) {
ISOException.throwIt(SW_INVALID_TRANSACTION_AMOUNT);
}

// check the new balance
if ((short) (balance + creditAmount) > MAX_BALANCE) {
ISOException.throwIt(SW_EXCEED_MAXIMUM_BALANCE);
}

// credit the amount
balance = (short) (balance + creditAmount);

} // end of deposit method

private void debit(APDU apdu) {

// access authentication
if (!pin.isValidated()) {
ISOException.throwIt(SW_PIN_VERIFICATION_REQUIRED);
}

byte[] buffer = apdu.getBuffer();

byte numBytes = (buffer[ISO7816.OFFSET_LC]);

byte byteRead = (byte) (apdu.setIncomingAndReceive());

if ((numBytes != 1) || (byteRead != 1)) {
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
}

// get debit amount
byte debitAmount = buffer[ISO7816.OFFSET_CDATA];

// check debit amount
if ((debitAmount > MAX_TRANSACTION_AMOUNT) || (debitAmount < 0)) {
ISOException.throwIt(SW_INVALID_TRANSACTION_AMOUNT);
}

// check the new balance
if ((short) (balance - debitAmount) < (short) 0) {
ISOException.throwIt(SW_NEGATIVE_BALANCE);
}

balance = (short) (balance - debitAmount);

} // end of debit method

private void getBalance(APDU apdu) {

byte[] buffer = apdu.getBuffer();

// inform system that the applet has finished
// processing the command and the system should
// now prepare to construct a response APDU
// which contains data field
short le = apdu.setOutgoing();

if (le < 2) {
ISOException.throwIt((byte) 0x6A86);
}

// informs the CAD the actual number of bytes
// returned
apdu.setOutgoingLength((byte) 2);

// move the balance data into the APDU buffer
// starting at the offset 0
buffer[0] = (byte) (balance >> 8);
buffer[1] = (byte) (balance & 0xFF);

// send the 2-byte balance at the offset
// 0 in the apdu buffer
apdu.sendBytes((short) 0, (short) 2);

} // end of getBalance method

private void verify(APDU apdu) {

byte[] buffer = apdu.getBuffer();
// retrieve the PIN data for validation.
byte byteRead = (byte) (apdu.setIncomingAndReceive());

// check pin
// the PIN data is read into the APDU buffer
// at the offset ISO7816.OFFSET_CDATA
// the PIN data length = byteRead
if (pin.check(buffer, ISO7816.OFFSET_CDATA, byteRead) == false) {
ISOException.throwIt(SW_VERIFICATION_FAILED);
}

} // end of validate method
} // end of class Wallet

下面是scr文件钱包.scr

    //Test script for Applet 'Wallet'

powerup;
// Select Wallet //aid/27ADED2B70/39
0x00 0xA4 0x04 0x00 0X06 0X27 0XAD 0XED 0X2B 0X70 0X3A 0x7F;

//Send the APDU here
//0x80 0xCA 0x00 0x00 <length> <data> 0x7F;
0x80 0x50 0x00 0x00 0x00 0x7F;
powerdown;

上面的wallet.scr,我用来查看余额,输出是:

CLA: 80, INS: 50, P1: 00, P2: 00, Lc: 00, Le: 02, 00, 00, SW1: 90, SW2: 00

这是预期的。但是当我尝试贷记和借记时,我应该怎么做呢?提前致谢

最佳答案

要调用贷记(或借记)方法,您需要更改 APDUINS 字节以匹配所​​需的值。

在您发布的代码中,CreditINS0x30INS借记0x40

因此在发送您选择的 APDU 后,您需要发送以下内容

信用

0x80 0x30 0x00 0x00 0x01 (1 byte containing the Credit value) 0x00

借方

0x80 0x30 0x00 0x00 0x01 (1 byte containing the Debit value) 0x00

在这两种情况下,您都应该收到 0x63 0x61 作为响应,表明您需要执行验证 PIN 命令。

验证 PIN 命令应构造为:

0x80 0x20 0x00 0x00 (1 byte indicating the number of PIN bytes) (The PIN bytes) 0x00

例如,如果 PIN 为4 位 并设置为值'1234',您会看到以下内容:

0x80 0x20 0x00 0x00 0x02 0x12 0x34 0x00

如果 PIN 码被验证正确,您将得到一个0x90 0x00作为响应

如果 PIN 码不正确,您将收到 0x63 0x00 响应

此应用程序的 PIN 值是在小程序的安装参数中设置的,顾名思义,当小程序安装到卡(或模拟器)上时

希望对你有帮助

关于java - 使用 Java Card 钱包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21284830/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com