APDU 命令是以下形式的二进制数队列:
CLA | INS | P1 | P2 | LC |数据 |乐
前四个部分,即 CLA 、 INS 、 P1 和 P2 在所有 APDU 命令中都是必需的每个都有一个字节长度。这些单字节长度的部分分别代表 Class、Instruction、Parameter1 和 Parameter2。
最后三个部分,即Lc、CData和Le是可选的。Lc是Nc的编码,也就是Nc的编码CDATA 字段的长度。 Le 是 Ne 的编码,然后是可能发送的最大响应数据的编码。根据这些部分的存在与否,我们为 APDU 命令提供了 4 种情况,如下所示:
- 案例1:
CLA | INS | P1 | P2
- 案例2:
CLA | INS | P1 | P2 | Le
- 案例3:
CLA | INS | P1 | P2 | Lc | Data
- 案例4:
CLA | INS | P1 | P2 | Lc | Data | Le
对于不同的命令和不同的小程序,CData 的长度是不同的。根据 CData 的长度(即 Lc)和可能发送的最大响应数据的长度(即 Le),我们必须输入 APDU 命令的类型:
-
Normal/Short APDU 命令,当 Lc 和 Le 小于
0xFF
-
扩展长度 APDU 命令,当 Lc 和/或 Le 大于
0xFF。
所以对于这些部分的长度,我们有:
Lc:1 个字节用于短 APDU 命令,3 个字节(它们指定此长度,因为它足够了)用于扩展 APDU 命令。
数据:不同的长度。
Le : 与 Lc 相同。
如何理解 APDU 命令?
答案:
当你编写一个applet 时,你指定你的applet 对不同的APDU 命令的响应,它将在未来接收到。 Card Manager 也是一个小程序。它支持的命令在您的卡的规格/数据表中定义。通常几乎所有卡都符合GlobalPlatform 和ISO7816,因此它们必须支持这些文档中定义的那些强制性APDU 命令。例如,0xA4 在 ISO7816-4 标准中被定义为 SELECT FILE 命令,如果你看到像xx A4 xx xx 这样的 APDU 正在发送到 Card Manager,你可以断定它与 @ 相关987654331@.
请注意,您可以为不同小程序中的不同功能选择一个值。例如,Applet1 在接收00 B0 xx xx APDU 命令时会返回0x6990,而Applet2 在接收同一命令时会返回0x6991:
小程序1:
public class SOQ extends Applet {
private SOQ() {
}
public static void install(byte bArray[], short bOffset, byte bLength)
throws ISOException {
new SOQ().register();
}
public void process(APDU arg0) throws ISOException {
byte buffer[] = arg0.getBuffer();
if(buffer[ISO7816.OFFSET_CLA] == (byte) 0x00 &&buffer[ISO7816.OFFSET_INS] == (byte) 0xB0){
ISOException.throwIt((short)0x6990);
}
}
}
输出:
OpenSC: opensc-tool.exe -s 00a404000b0102030405060708090000 -s 00B00000 -s 00B00
100
Using reader with a card: ACS CCID USB Reader 0
Sending: 00 A4 04 00 0B 01 02 03 04 05 06 07 08 09 00 00
Received (SW1=0x90, SW2=0x90)
Sending: 00 B0 00 00
Received (SW1=0x69, SW2=0x90)
Sending: 00 B0 01 00
Received (SW1=0x69, SW2=0x90)
小程序2:
public class SOQ extends Applet {
private SOQ() {
}
public static void install(byte bArray[], short bOffset, byte bLength)
throws ISOException {
new SOQ().register();
}
public void process(APDU arg0) throws ISOException {
byte buffer[] = arg0.getBuffer();
if(buffer[ISO7816.OFFSET_CLA] == (byte) 0x00 && buffer[ISO7816.OFFSET_INS] == (byte) 0xB0){
ISOException.throwIt((short)0x6991);
}
}
}
输出:
OpenSC: opensc-tool.exe -s 00a404000b0102030405060708090000 -s 00B00000 -s 00B00
100
Using reader with a card: ACS CCID USB Reader 0
Sending: 00 A4 04 00 0B 01 02 03 04 05 06 07 08 09 00 00
Received (SW1=0x90, SW2=0x00)
Sending: 00 B0 00 00
Received (SW1=0x69, SW2=0x91)
Sending: 00 B0 01 00
Received (SW1=0x69, SW2=0x91)
因此,您的问题(我如何理解 APDU 命令?)的最终简短答案是:
注意:我们的 APDU 响应几乎相同。