JavaCard 2.2.2中ISO7816.SW_PIN_REQUIRED的替代方法是什么?

时间:2015-06-04 01:34:55

标签: javacard

我正在使用JavaCard 2.2.2。

以下程序无效,因为ISO7816.SW_PIN_REQUIRED找不到任何要解决的库。

如何将ISO7816.SW_PIN_REQUIRED替换为任何其他常量以使程序运行?

package monpackage;

import javacard.framework.*;
//import javacardx.framework.*;

public class Wallet extends Applet 
{
/* constants declaration */
    // code of CLA byte in the command APDU header
    final static byte Wallet_CLA =(byte)0xB0;
    // codes of INS byte in the command APDU header
    final static byte Deposit = (byte) 0x10;
    final static byte Debit = (byte) 0x20;
    final static byte Balance = (byte) 0x30;
    final static byte Validate = (byte) 0x40;
    // maximum number of incorrect tries before the
    // PIN is blocked
    final static byte PinTryLimit =(byte)0x03;
    // maximum size PIN
    final static byte MaxPinSize =(byte)0x04;
    // status word (SW1-SW2) to signal that the
    // balance becomes negative;
    final static short SW_NEGATIVE_BALANCE = (short)0x6910;
    /* instance variables declaration */
    OwnerPIN pin;
    byte balance;
    byte buffer[]; // APDU buffer
    private Wallet() 
    {
        // It is good programming practice to allocate
        // all the memory that an applet needs during
        // its lifetime inside the constructor
        pin = new OwnerPIN(PinTryLimit, MaxPinSize);
        balance = 0;
        register();
    } // end of the constructor

    public static void install(APDU apdu)
    {
        // create a Wallet applet instance
        new Wallet();
    } // end of install method

    public boolean select() 
    {
        // reset validation flag in the PIN object to
        // false
        pin.reset();
        // returns true to JCRE to indicate that the
        // applet is ready to accept incoming APDUs.
        return true;
    }// end of select method

    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
        buffer = apdu.getBuffer();
        // verify that if the applet can accept this
        // APDU message
        if (buffer[ISO7816.OFFSET_CLA] !== Wallet_CLA)
        {
            ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
        }

        switch (buffer[ISO7816.OFFSET_INS]) 
        {
          case Balance:   getBalance(apdu); return;
          case Debit:   debit(apdu); return;
          case Deposit:   deposit(apdu);return;
          case Validate:    validate(apdu);return
          default:   ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
        }
    }   // end of process method

    private void deposit(APDU apdu) {
        // access authentication
        if ( ! pin.isValidated() )
          ISOException.throwIt (ISO7816.SW_PIN_REQUIRED);
        // Lc byte denotes the number of bytes in the
        // data field of the comamnd APDU
        byte numBytes = (byte) (buffer[ISO7816.OFFSET_LC]);
        // indicate that this APDU has incoming data and
        // receive data starting from the offset
        // ISO.OFFSET_CDATA
        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 (byteRead != 1)
          ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
        // increase the balance by the amount specified
        // in the data field of the command APDU.
        balance = (byte)
          (balance + buffer[ISO7816.OFFSET_CDATA]);
        // return successfully
        return;
        } // end of deposit method

    private void debit(APDU apdu) {
        // access authentication
        if ( ! pin.isValidated() )
          ISOException.throwIt(ISO7816.SW_PIN_REQUIRED);
        byte numBytes = (byte)(buffer[ISO7816.OFFSET_LC]);
        byte byteRead =
        (byte)(apdu.setIncomingAndReceive());
        if (byteRead != 1)
          ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
        // balance can not be negative
        if ( ( balance - buffer[ISO7816.OFFSET_CDATA]) < 0 )
          ISOException.throwIt(SW_NEGATIVE_BALANCE);
        balance = (byte)
          (balance - buffer[ISO7816.OFFSET_CDATA]);
        } // end of debit method

    private void getBalance(APDU apdu) {
        // access authentication
        if ( ! pin.isValidated() )
          ISOException.throwIt(ISO7816.SW_PIN_REQUIRED);
        // 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
        apdu.setOutgoing();
        //indicate the number of bytes in the data field
        apdu.setOutgoingLength((byte)1);
        // move the data into the APDU buffer starting
        // at offset 0
        buffer[0] = balance;
        // send 1 byte of data at offset 0 in the APDU
        // buffer
        apdu.sendBytes((short)0, (short)1);
        } // end of getBalance method
    private void validate(APDU apdu) {
        // retrieve the PIN data which requires to be
        // valid ated. The user interface data is
        // stored in the data field of the APDU
        byte byteRead =
        (byte)(apdu.setIncomingAndReceive());
        // validate user interface and set the
        // validation flag in the user interface
        // object to be true if the validation.
        // succeeds. If user interface validation
        // fails, PinException would be thrown from
        // the pin.check() method.
        pin.check(buffer, ISO7816.OFFSET_CDATA, byteRead);
        } // end of validate method
        } // end of class Wallet

1 个答案:

答案 0 :(得分:4)

再次查看Java Card 2.2.2 API Specifications - ISO7816 Interface。 :)

您将看到此界面中没有名为SW_PIN_REQUIRED的字段。您只需在程序的常量声明部分添加以下行,然后将ISO.SW_PIN_REQUIRED替换为SW_PIN_REQUIRED

final static short SW_PIN_REQUIRED = 0x6968

此外,您可以使用ISO7816的以下已定义字段,而不是未定义字段SW_PIN_REQUIRED

ISO7816.SW_CONDITIONS_NOT_SATISFIED

ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED

BTW这些是规范中定义的一些特殊短值,您不必在程序中使用相同的值。例如,编译器在编译时将ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED替换为0x6982(如API规范中所述),当您与卡上的applet通信时,您将看到此值。因此,您只需定义特殊状态字,而不是使用这些值(不推荐)。

编辑(感谢Bodewes先生)

正如Bodewes先生在评论中所说,我们强烈建议您继续使用ISO/IEC 7816 - 3 Standard4中定义的可能状态字范围。如果我们不这样做,我们可能会遇到麻烦,特别是对于T = 0(面向字节的接触模式)操作。

从7816-3:“如果值是'6X'或'9X',除了'60',它是一个SW1字节。它不要求数据传输动作。接口设备应等待一个字符传送SW2字节。对SW2值没有限制。“因此需要6X或9X才能与T = 0兼容。