SELECT APDU 不能正常工作

SELECT APDU doesn't work fine

我创建了一个包(AID=0102030405),里面有两个小程序。

这是第一个小程序 (AID=01020304050202020202) 的程序,它将 bArray 的内容存储到静态文件中,returns 它在处理方法中:

package processMethodArguments;

import javacard.framework.APDU;
import javacard.framework.Applet;
import javacard.framework.ISOException;
import javacard.framework.Util;

public class ArgumentReturner extends Applet {
//this is my static field that I want store bArray (the install method argument) in it.
    public static byte[] theArray={(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff};
    public static short arrayLength=(short)0xFF;

    private ArgumentReturner() {
    }

    public static void install(byte bArray[], short bOffset, byte bLength)
            throws ISOException {

        new ArgumentReturner().register();

        //Storing bArray in theArray.
        ArgumentReturner.arrayLength=(short)bArray.length;
        Util.arrayCopyNonAtomic(bArray, (short)0,ArgumentReturner.theArray , (short) 0, ArgumentReturner.arrayLength);    


    }

    public void process(APDU apdu) throws ISOException {
        //returning theArray (=bArray) in response of any command.
        byte[] buffer=apdu.getBuffer();
        Util.arrayCopyNonAtomic(ArgumentReturner.theArray, (short)0,buffer , (short) 0, ArgumentReturner.arrayLength); 
        apdu.setOutgoingAndSend((short)0, (short)255);
    }

}

这是第二个小程序 (AID=010203040502) 什么都不做的程序:

package processMethodArguments;

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

public class SecondApplet extends Applet {

    private SecondApplet() {
    }

    public static void install(byte bArray[], short bOffset, byte bLength)
            throws ISOException {
        new SecondApplet().register();
    }

    public void process(APDU arg0) throws ISOException {
        // Nothing to do. So in reception of any command, it must return only 0x9000

    }

}

我成功转换并在我的卡上安装了这个包:

GP: gp -install D:\bArrayAccessibility\processMethodArguments.cap

GP: gp -list
AID: A000000151000000 (|....Q...|)
     ISD OP_READY: Security Domain, Card lock, Card terminate, Default selected,
 CVM (PIN) management

AID: 01020304050202020202 (|..........|)
     App SELECTABLE: (none)

AID: A0000001515350 (|....QSP|)
     ExM LOADED: (none)
     A000000151535041 (|....QSPA|)

AID: 0102030405 (|.....|)
     ExM LOADED: (none)
     01020304050202020202 (|..........|)
     010203040502 (|......|)


GP: gp -create 010203040502 -package 0102030405 -applet 010203040502

GP: gp -list
AID: A000000151000000 (|....Q...|)
     ISD OP_READY: Security Domain, Card lock, Card terminate, Default selected,
 CVM (PIN) management

AID: 01020304050202020202 (|..........|)
     App SELECTABLE: (none)

AID: 010203040502 (|......|)
     App SELECTABLE: (none)

AID: A0000001515350 (|....QSP|)
     ExM LOADED: (none)
     A000000151535041 (|....QSPA|)

AID: 0102030405 (|.....|)
     ExM LOADED: (none)
     01020304050202020202 (|..........|)
     010203040502 (|......|)


GP:

现在,问题是:当我 select 第一个小程序或第二个小程序时,都 returns APDU 缓冲区 (=theArray) :

OpenSC: opensc-tool -s 00a404000a01020304050202020202
Using reader with a card: ACS CCID USB Reader 0
Sending: 00 A4 04 00 0A 01 02 03 04 05 02 02 02 02 02
Received (SW1=0x90, SW2=0x00):
0A 01 02 03 04 05 02 02 02 02 02 01 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ...............

OpenSC: opensc-tool -s 00a4040006010203040502
Using reader with a card: ACS CCID USB Reader 0
Sending: 00 A4 04 00 06 01 02 03 04 05 02
Received (SW1=0x90, SW2=0x00):
0A 01 02 03 04 05 02 02 02 02 02 01 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ...............

OpenSC:

问:为什么会这样?

为什么两个命令都选择第一个小程序?

AID 是分级的。 Java Card 运行时简单地选择第一个匹配给定字节的,即使 AID 包含更多字节。如果您再次发射 SELECT,它可能 select 第二个。

要解决此问题,请提供即使对于最短 AID 中的字节也是不同的 Applet AID。