如何在Java卡技术中获取用于验证钱包应用的PIN码?

时间:2015-05-25 14:38:26

标签: javacard

我无法获得经典Java卡应用程序的密码。我必须编写APDU命令来验证PIN码。

请帮我解释如何获取密码

**Wallet.java**

package wallet;

import javacard.framework.*;

public class Wallet extends Applet {

    /**
    * Installs this applet.
    * 
    * @param bArray the array containing installation parameters
    * @param bOffset
    * the starting offset in bArray @param bLength
    * the length in bytes of the parameter data in bArray
    */


    // 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 VERIFY = (byte)0x20;
    final static byte CREDIT = (byte)0x30;
    final static byte DEBIT = (byte)0x40;
    final static byte GET_BALANCE = (byte)0x50;

    // maximum balance $32,76
    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;

    protected 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);

        // The installation parameters contain the PIN initialization value
        //        pin.update(bArray, bOffset, bLength);
        // Above command causes error.
        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();
    }

    /**
    * Processes an incoming APDU.
    * 
    * @see APDU
    * @param apdu
    * the incoming APDU
    */

    public void process(APDU apdu) {
        byte buffer[] = apdu.getBuffer();
        // check SELECT APDU command 
        if ((buffer[ISO7816.OFFSET_CLA] == 0) && (buffer[ISO7816.OFFSET_INS] == (byte)(0xA4)) )
            return;
        // 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 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);

    }

}


**wallet.scr**

powerup;
// Select Wallet //aid/B239C74B30/39
0x00 0xA4 0x04 0x00 0x06 0xB2 0x39 0xC7 0x4B 0x30 0x3A 0x7F;  // check 0x3A 0x7f

//Send the APDU here 
// verify
0xB0 0x20 0x00 0x00 0x06 0xB2 0x39 0xC7 0x4B 0x30 0x3A 0x7F;

// credit
0xB0 0x30 0x00 0x00 0x01 0x09 0x7F;
//0x80 0xCA 0x00 0x00 <length> <data> 0x7F;

// debit
0xB0 0x40 0x00 0x00 0x01 0x05 0x7F;

// getBalance
0xB0 0x50 0x00 0x00 0x01 0x7F 0x02;
powerdown;

当我尝试更新引脚时,响应为69 99 什么应该是安装applet的APDU命令。

1 个答案:

答案 0 :(得分:0)

在上面的代码中你似乎想要的是将Applet AID作为引脚值。在这种情况下,您可以检查AID是否小于MAX_PIN_SIZE。 另外,更改构造函数,如下所示

protected 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);

    // The installation parameters contain the PIN initialization value
    pin.update(bArray, bOffset + 1, bArray[bOffset]);
    // Above command causes error.
    register();

} // end of the constructor

它将确保只将AID值传递给pin.update(),但仍需要确保您的AID长度小于MAX_PIN_SIZE,否则将抛出PINException.ILLEGAL_VALUE。