使用APDU命令获取卡的某些信息

mar*_*yes 2 java apdu smartcard emv smartcard-reader

我有一个终端,它有自己的API来固定和发送芯片和终端之间的命令,有一个功能,它发送APDU命令并以字节数组返回答案.

例如,如果想要读取标签5A(应用程序PAN),我发送以下命令:

byte[] byteArrayAPDU = new byte[]{(byte)0x00, (byte)0xCA, (byte)0x00, (byte)0x5A};
int nResult = SmartCardInterface.transmit(nCardHandle, byteArrayAPDU, byteArrayResponse);
Run Code Online (Sandbox Code Playgroud)

该变量byteArrayResponse获得对APDU命令的响应.

当我将值转换byteArrayAPDU为十六进制数字字符串时,这给了我:00 CA 00 5A.并且对该命令的响应是6E 00(类不受支持).

我的设备使用ISO 7816作为技术规格.我发送APDU命令的方式是否正确?我问这个是因为我已经读过APDU命令至少必须有5个值,但我不知道在第五个参数中要发送什么.我不知道答案的长度是什么.

您能举例说明如何在APDU命令中获取标签5A或其他内容吗?

如果命令正确,取代我6E 00此刻看到的位置,我会在投射到字符串时将信息看作纯文本吗?

Mic*_*and 12

您在问题中显示的输入和输出值表明您对方法的使用transceive()是正确的,即第二个参数是命令APDU,第三个参数用响应APDU填充:

resultCode = SmartCardInterface.transmit(cardHandle, commandAPDU, ResponseAPDU);
Run Code Online (Sandbox Code Playgroud)

您关于APDU命令的格式和有效性的问题相当广泛.通常,APDU的格式和一组基本命令在ISO/IEC 7816-4中定义.由于您使用标记了问题并提及了应用程序主帐号,因此您可能正在与某种形式的EMV支付卡进行交互(例如,来自其中一个主要方案的信用卡或借记卡).在这种情况下,您可能希望研究EMV支付系统的各种规范,这些规范定义了这些卡的数据结构和特定于应用程序的命令.

关于您的具体问题:

APDU总是至少包含5个字节吗?

不,当然不是.命令APDU至少包含4个字节(标头字节).这些是

+-----+-----+-----+-----+
| CLA | INS | P1  | P2  |
+-----+-----+-----+-----+

这种4字节的APDU称为"情况1".这意味着命令APDU不包含发送到卡的数据字段,并且不期望卡生成响应数据字段.因此,响应APDU应仅包含响应状态字:

+-----+-----+
| SW1 | SW2 |
+-----+-----+

命令APDU的第5个字节是什么?

第5个字节是长度字段(或者在扩展长度APDU的情况下长度字段的一部分,我将在本文中不再进一步解释).根据具体情况,此长度字段可能有两个含义:

  1. 如果命令APDU没有数据字段,则该长度字段指示响应数据字段的预期长度(Ne):

    +-----+-----+-----+-----+-----+
    | CLA | INS | P1  | P2  | Le  |
    +-----+-----+-----+-----+-----+
    
    • Le = 0x01 .. 0xFF:这意味着预期的响应数据长度Ne是1,2,... 255字节(即恰好是Le的值).
    • Le = 0x00:这意味着预期的响应数据长度Ne是256字节.这通常用于指示卡为您提供尽可能多的字节(最多256个字节).因此,即使Le设置为0x00,您也不会总是从卡中获得256个字节.
  2. 如果命令APDU本身具有数据字段,则该长度字段指示命令数据字段的长度(Nc):

    +-----+-----+-----+-----+-----+-----------------+
    | CLA | INS | P1  | P2  | Lc  | DATA (Nc bytes) |
    +-----+-----+-----+-----+-----+-----------------+
    
    • Lc = 0x01 ... 0xFF:这意味着命令数据长度Nc是1,2,... 255字节(即恰好是Lc的值).
    • Lc = 0x00:这用于指示扩展长度APDU.
  3. 如果存在命令数据字段并且该命令期望生成响应数据,则该命令APDU可以再次跟随Le字段:

    +-----+-----+-----+-----+-----+-----------------+-----+
    | CLA | INS | P1  | P2  | Lc  | DATA (Nc bytes) | Le  |
    +-----+-----+-----+-----+-----+-----------------+-----+
    

命令00 CA 00 5A是否正确?

可能不是,原因有以下几点:

  1. 由于您希望卡提供响应数据字段(即数据对象0x5A),因此您需要指定Le字段.因此,有效的格式将是

    +------+------+------+------+------+
    | CLA  | INS  | P1   | P2   | Le   |
    +------+------+------+------+------+
    | 0x00 | 0xCA | 0x00 | 0x5A | 0x00 |
    +------+------+------+------+------+
    
  2. 您将收到状态字6E 00以响应该命令.此状态字的含义是" class not supported ".这表示当前状态不支持CLA字节设置为0x00的命令.对于某些卡,这也仅仅意味着00 CA不支持CLA和INS()的这种组合,尽管这与ISO/IEC 7816-4中的定义相矛盾.

    总的来说,您可以假设您的卡在其当前执行状态下不支持此命令.

  3. 假设您正在与EMV支付卡进行交互,通常需要先选择一个应用程序.你的问题并不表明你是否已经这样做了,所以我想,你现在不这样做.通过发送SELECT(通过AID)命令来选择应用程序:

    +------+------+------+------+------+-----------------+------+
    | CLA  | INS  | P1   | P2   | Le   | DATA            | Le   |
    +------+------+------+------+------+-----------------+------+
    | 0x00 | 0xA4 | 0x04 | 0x00 | 0xXX | Application AID | 0x00 |
    +------+------+------+------+------+-----------------+------+
    

    当然,应用程序AID的值取决于卡应用程序,可以通过遵循EMV规范中定义的发现过程来获得.

  4. 即使在应用程序选择之后,EMV应用程序的GET DATA APDU命令也在专有类中定义.因此,CLA字节必须设置为0x80:

    +------+------+------+------+------+
    | CLA  | INS  | P1   | P2   | Le   |
    +------+------+------+------+------+
    | 0x80 | 0xCA | 0x00 | 0x5A | 0x00 |
    +------+------+------+------+------+
    
  5. 最后,即便如此,我也不知道任何卡允许您通过GET DATA命令检索PAN的方案.通常,PAN只能通过基于文件/记录的访问来访问.由于您没有透露卡的具体类型/品牌,因此无法确定您的卡可能或可能不支持的卡.