默认选择的小程序没有 return 正确的值
Default selected applet doesn't return right value
我想回答 问题所以我写了下面的程序:
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
//.
将上述小程序安装为默认选择的小程序后,我收到以下结果:
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_P2+1]
替换了 buf[ISO7816.OFFSET_EXT_CDATA]
,现在它如我所愿:
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
!我在A0C0000023
APDU命令中被认为是0x23
,必须考虑为Le
!(而不是Lc
)。
A0
和 A4
是大于 128 的值。不幸的是,Java 卡字节已签名。在比较之前,您必须将 short
常量转换为 bytes
。
我想回答
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
//.
将上述小程序安装为默认选择的小程序后,我收到以下结果:
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_P2+1]
替换了 buf[ISO7816.OFFSET_EXT_CDATA]
,现在它如我所愿:
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
!我在A0C0000023
APDU命令中被认为是0x23
,必须考虑为Le
!(而不是Lc
)。
A0
和 A4
是大于 128 的值。不幸的是,Java 卡字节已签名。在比较之前,您必须将 short
常量转换为 bytes
。