你所展示的输入和输出值表明你在使用transceive()
方法时是正确的,即第二个参数是一个命令APDU,第三个参数则装有响应APDU:
resultCode = SmartCardInterface.transmit(cardHandle, commandAPDU, ResponseAPDU);
您对APDU命令的格式和有效性的问题比较广泛。一般而言,APDU的格式和基本指令集在ISO/IEC 7816-4中定义。由于您标记了问题
emv并提到了应用程序主帐号,您可能正在与某种EMV支付卡(例如来自主要方案之一的信用或借记卡)交互。在这种情况下,您可能需要研究各种EMV支付系统的规范,这些规范定义了这些卡的数据结构和应用程序特定的命令。
关于您具体的问题:
APDU是否总是至少由5个字节组成?
不是的。命令APDU至少由4个字节(标题字节)组成。它们是:
+-----+-----+-----+-----+
| CLA | INS | P1 | P2 |
+-----+-----+-----+-----+
一种4字节的APDU被称为“case 1”。这意味着命令APDU不包含发送到卡片的数据字段,并且不期望卡片生成响应数据字段。因此,响应APDU只包含响应状态字:
+-----+-----+
| SW1 | SW2 |
+-----+-----+
命令APDU的第5个字节是什么?
第5个字节是长度字段(对于扩展长度APDU的情况,这是长度字段的一部分,本文不再进一步解释)。根据情况,该长度字段可能有两个含义:
如果命令APDU没有数据域,则长度字段表示响应数据域的预期长度(Ne):
+-----+-----+-----+-----+-----+
| CLA | INS | P1 | P2 | Le |
+-----+-----+-----+-----+-----+
Le = 0x01 .. 0xFF:这意味着预期的响应数据长度Ne为1、2、... 255字节(即Le的确切值)。
Le = 0x00:这意味着预期的响应数据长度Ne为256字节。这通常用于指示卡提供尽可能多的字节(最多256字节)。因此,即使将Le设置为0x00,您也不会总是从卡中获得确切的256字节。
如果命令APDU本身具有数据域,则该长度字段表示命令数据域的长度(Nc):
+-----+-----+-----+-----+-----+-----------------+
| CLA | INS | P1 | P2 | Lc | DATA(Nc个字节)|
+-----+-----+-----+-----+-----+-----------------+
Lc = 0x01 .. 0xFF:这意味着命令数据长度Nc为1、2、... 255字节(即Lc的确切值)。
Lc = 0x00:这用于指示扩展长度APDU。
如果存在命令数据域并且期望生成响应数据的命令APDU可能再次跟随Le字段:
+-----+-----+-----+-----+-----+-----------------+-----+
| CLA | INS | P1 | P2 | Lc | DATA(Nc个字节)| Le |
+-----+-----+-----+-----+-----+-----------------+-----+
命令00 CA 00 5A
是否正确?
可能不正确,原因如下:
- 由于您期望卡片返回响应数据字段(即数据对象0x5A),因此需要指定Le字段。因此,有效的格式应为:
+------+------+------+------+------+
| CLA | INS | P1 | P2 | Le |
+------+------+------+------+------+
| 0x00 | 0xCA | 0x00 | 0x5A | 0x00 |
+------+------+------+------+------+
- 您会收到响应中的状态字
6E 00
。该状态字的含义是“不支持的类”。这表明CLA字节设置为0x00的命令在当前状态下不受支持。对于某些卡片,这也意味着该CLA和INS的组合(00 CA
)不受支持,尽管这与ISO/IEC 7816-4中的定义相矛盾。
总体而言,可以假设您的卡片在其当前执行状态下不支持此命令。
- 假设您正在与EMV支付卡交互,通常需要首先选择一个应用程序。您的问题没有表明您是否已经这样做,因此我假设您现在还没有这样做。通过发送SELECT(by AID)命令来选择应用程序:
+------+------+------+------+------+-----------------+------+
| CLA | INS | P1 | P2 | Le | DATA | Le |
+------+------+------+------+------+-----------------+------+
| 0x00 | 0xA4 | 0x04 | 0x00 | 0xXX | Application AID | 0x00 |
+------+------+------+------+------+-----------------+------+
应用程序AID的值当然取决于卡片应用程序,并可以通过遵循EMV规范中定义的发现过程来获取。
- 即使在选择应用程序之后,EMV应用程序的GET DATA APDU命令也是在专有类中定义的。因此,CLA字节必须设置为0x80:
+------+------+------+------+------+
| CLA | INS | P1 | P2 | Le |
+------+------+------+------+------+
| 0x80 | 0xCA | 0x00 | 0x5A | 0x00 |
+------+------+------+------+------+
- 最后,即使如此,我也不知道任何计划允许您通过GET DATA命令检索PAN的方案。通常,只能通过基于文件/记录的访问才能访问PAN。由于您没有透露特定类型/品牌的卡片,因此无法确定您的卡片实际上支持什么或不支持什么。