默认选定的小程序不会返回正确的值

时间:2015-07-15 07:58:41

标签: javacard

我想回答this问题所以我编写了以下程序:

package test;

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

public class Test extends Applet {

    public static final byte[] res = { (byte) 0x00, (byte) 0x00, (byte) 0x3B,
            (byte) 0xAD, (byte) 0x3F, (byte) 0x00, (byte) 0x01, (byte) 0x00,
            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x16,
            (byte) 0xB3, (byte) 0x03, (byte) 0x06, (byte) 0x04, (byte) 0x00,
            (byte) 0x83, (byte) 0x8A, (byte) 0x83, (byte) 0x8A, (byte) 0x00,
            (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x3B, (byte) 0xAD,
            (byte) 0x00, (byte) 0x00, (byte) 0x3B, (byte) 0xAD, (byte) 0x2F,
            (byte) 0x06, (byte) 0x02 };

    public static void install(byte[] bArray, short bOffset, byte bLength) {
        new test.Test()
                .register(bArray, (short) (bOffset + 1), bArray[bOffset]);
    }

    public void process(APDU apdu) {
        if (selectingApplet()) {
            return;
        }

        byte[] buf = apdu.getBuffer();

        if (buf[ISO7816.OFFSET_CLA] == 0xA0 && buf[ISO7816.OFFSET_INS] == 0xA4 && buf[ISO7816.OFFSET_P1] == 0x00 && buf[ISO7816.OFFSET_P2] == 0x00
                && buf[ISO7816.OFFSET_LC] == 0x02 && buf[ISO7816.OFFSET_LC+1] == 0x7F && buf[ISO7816.OFFSET_LC+2] == 0x20) {
            ISOException.throwIt((short) 0x9F23);
        } else if (buf[ISO7816.OFFSET_CLA] == 0xA0 && buf[ISO7816.OFFSET_INS] == 0xC0 && buf[ISO7816.OFFSET_P1] == 0x00
                && buf[ISO7816.OFFSET_P2] == 0x00 && buf[ISO7816.OFFSET_EXT_CDATA] == 0x23) {
            Util.arrayCopyNonAtomic(res, (short)0, buf, (short)0, (short)35);
            apdu.setOutgoingAndSend((short)0, (short)35);

        }
                else
                    ISOException.throwIt((short)0x9090);
    }
}

使用GlobalPlatformPro工具将其安装为默认设置:

CMD> gp -install e:\soq.cap -default

CMD>

好吧,现在,我期待以下沟通:

>> in: 0xA0 A4 00 00 02 7F 20 
<< out: 0x9F 23 
>> in : 0xA0 C0 00 00 23 
<< out: 0x00 00 3B AD 3F 00 01 00 00 00 00 00 16 B3 03 06 04 00 83 8A 83 8A 00 03 00 00 3B AD 00 00 3B AD 2F 06 02

但实际上,我使用OpenSC进行了以下沟通:

CMD> OSC.exe -s A0A40000027F20 -s a0c0000023
Using reader with a card: ACS CCID USB Reader 0
Sending: A0 A4 00 00 02 7F 20
Received (SW1=0x90, SW2=0x90)
Sending: A0 C0 00 00 23
Received (SW1=0x90, SW2=0x90)

更新

亲爱的@Vojta在回答中说,我将常量转换为字节如下:

//.
//. These parts didn't changed
//.

public void process(APDU apdu) {
    if (selectingApplet()) {
        return;
    }

    byte[] buf = apdu.getBuffer();

    if (buf[ISO7816.OFFSET_CLA] == (byte)0xA0 && buf[ISO7816.OFFSET_INS] == (byte) 0xA4 && buf[ISO7816.OFFSET_P1] == (byte) 0x00&& buf[ISO7816.OFFSET_P2] == (byte) 0x00 
            && buf[ISO7816.OFFSET_LC] == (byte) 0x02 && buf[ISO7816.OFFSET_LC + 1] == (byte) 0x7F  && buf[ISO7816.OFFSET_LC + 2] == (byte) 0x20) {
        ISOException.throwIt((short) 0x9F23);
    } else if (buf[ISO7816.OFFSET_CLA] == (byte) 0xA0 && buf[ISO7816.OFFSET_INS] == (byte) 0xC0  && buf[ISO7816.OFFSET_P1] == (byte) 0x00 
            && buf[ISO7816.OFFSET_P2] == (byte) 0x00  && buf[ISO7816.OFFSET_EXT_CDATA] == (byte) 0x23 ) {
        Util.arrayCopyNonAtomic(res, (short) 0, buf, (short) 0, (short) 35);
        apdu.setOutgoingAndSend((short) 0, (short) 35);

    } else {
        ISOException.throwIt((short) 0x9090);
    }

//.
//. These parts didn't changed
//.

将上述applet作为默认选择的applet安装后,我收到以下reslts:

CommandLine> OSC.exe -s A0A40000027F20 -s a0c0000023
Using reader with a card: ACS CCID USB Reader 0
Sending: A0 A4 00 00 02 7F 20
Received (SW1=0x9F, SW2=0x23)
Sending: A0 C0 00 00 23
Received (SW1=0x90, SW2=0x90)

好吧,如上所述,我收到第一个APDU命令的正确答案,但第二个APDU命令的答案并不像我们预期的那样。

我修改第二个比较部分如下:

//.
//. These parts didn't changed
//.

else if (buf[ISO7816.OFFSET_CLA] == (byte) 0xA0 && buf[ISO7816.OFFSET_INS] == (byte) 0xC0  && buf[ISO7816.OFFSET_P1] == (byte) 0x00 
                && buf[ISO7816.OFFSET_P2] == (byte) 0x00  && buf[ISO7816.OFFSET_P2+1] == (byte) 0x23 ) { 

//.
//. These parts didn't changed
//.

好吧,如您所见,我将buf[ISO7816.OFFSET_EXT_CDATA]替换为buf[ISO7816.OFFSET_P2+1],现在它可以按照我的意愿运行:

CommandLine> OSC.exe -s A0A40000027F20 -s a0c0000023
Using reader with a card: ACS CCID USB Reader 0
Sending: A0 A4 00 00 02 7F 20
Received (SW1=0x9F, SW2=0x23)
Sending: A0 C0 00 00 23
Received (SW1=0x90, SW2=0x00):
00 00 3B AD 3F 00 01 00 00 00 00 00 16 B3 03 06 ..;.?...........
04 00 83 8A 83 8A 00 03 00 00 3B AD 00 00 3B AD ..........;...;.
2F 06 02                                        /..

我不知道为什么我必须使用ISO7816.OFFSET_P2+1代替ISO7816.OFFSET_EXT_CDATA!我在0x23 APDU命令中被认为是A0C0000023,必须考虑为Le!(而不是Lc)。

1 个答案:

答案 0 :(得分:3)

A0A4的值大于128.遗憾的是,Java Card字节已签名。在比较之前,您必须将short常量强制转换为bytes