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

时间:2016-11-17 19:30:15

标签: java smartcard apdu smartcard-reader emv

我有一个终端,它有自己的API来在芯片和终端之间建立和发送命令,有一个函数可以传输APDU命令并以字节数组的形式返回答案。

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

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

变量byteArrayResponse获取对APDU命令的响应。

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

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

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

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

3 个答案:

答案 0 :(得分:11)

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

resultCode = SmartCardInterface.transmit(cardHandle, commandAPDU, ResponseAPDU);

关于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  |
    +-----+-----+-----+-----+-----+-----------------+-----+
    
  4. 命令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的命令。对于某些卡,这也仅仅意味着不支持CLA和INS(00 CA)的这种组合,尽管这与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只能通过基于文件/记录的访问来访问。由于您没有透露卡的具体类型/品牌,因此无法确定您的卡可能支持或不支持的内容。

答案 1 :(得分:3)

开始时

标准ISO 7816包括几个部分。 当终端设备供应商注意到ISO 7816时,他们只是确认公共物理特性(第1部分),尺寸和触点(第2部分)和传输协议(第3部分)已应用于设备读取器。

ISO 7816第4部分中定义的APDU命令和响应(以及其他一些部分)是通用定义,您的智能卡可能不完全支持。

您需要了解与您的卡片类型相关的卡片终端互动图层:

  • EMV是支付卡的ISO 7816的自定义版本。
  • Global Card Brands使用基于EMV和ISO 7816的自定义规格。适用于样品Amex" AEIPS",Diners" D-PAS",MasterCard" M / Chip&# 34;,Visa" VIS"等。它们几乎相同,与支持的命令,流程和标签列表相关的细微差别。

不幸的是,大多数支付卡都不应该使用 GET DATA APDU命令返回Tag 0x5A值。通常您需要遵循付款程序。至少 SELECT 卡片应用程序和阅读 SFI 卡片记录中的标记值。

根据EMV GET DATA P1 P2值应该用于标签0x9F36,0x9F13,0x9F17或0x9F4F。

回答你的问题:

第五个参数要发送什么?回复的长度是多少?

第五个字节称为" Le" - 预期数据的长度。您可以尝试使用Le =" 00 "。 如果卡支持APDU命令,则可以将SW1SW2设为0x" 6Cxx "其中 xx 是所请求数据的十六进制长度。当您可以使用正确的Le值重复相同的命令时。

如需样品,请阅读PIN计数器

Get Data (Tag = '9F 17')
Request : 80 CA 9F 17 00
Response: 6C 04
    SW1 SW2: 6C 04 (SW_Warning Wrong length(Le))

Get Data (Tag = '9F 17')
Request : 80 CA 9F 17 04
Response: 9F 17 01 00 90 00
    Data     : 9F 17 01 03 // Tag + Length + Value
        Tag 9F 17: Personal Identification Number (PIN) Try Counter : 03
    SW1 SW2  : 90 00 (SW_OK)

如果命令在令人满意的地方看到6E 00,那么在回答字符串的时候我会把这些信息视为纯文字吗?

使用BYTE编码的APDU命令和响应。根据提供的终端API示例,您将获得字节数组。

作为开发人员,您可以将字节转换为所需格式或按原样使用。请记住,根据EMV规范,标签数据的格式可以是变量:

  • HEX (或二进制),用于数字标记的示例,例如金额;
  • BCD 表示日期/时间的样本或某些数字(如货币)。 PAN也是BCD编码器;
  • 不同字符集(ASCII,Unicode,...)中的字符串,用于持卡人姓名,应用程序名称的样本。

标签0x5A - 应用主帐号(PAN)编码为BCD,在奇数PAN长度的情况下可以用0xF填充。

答案 2 :(得分:1)

回答如何阅读您的特定标签数据,因为已经回答了APDU和应用程序状态行为。 在SELECT应用程序之后,您可以启动GET PROCESSING OPTIONS。这是交易的实际开始。在这里,您将返回一个名为AFL(应用程序文件定位器)的标签。您需要解析此元素并执行多个READ RECORDS,直到找到数据。 AFL是一组四字节数据(如果有两组SFI,则会有八个字节数据)。

  • 第一个字节表示SFI(5个最重要的字节是P2的输入 阅读记录)。第二个字节表示要读取的第一个记录(输入 到READ RECORD的P1)。第三个字节表示要读取的最后一个记录。( 你需要多次循环READ RECORD)第四个字节是donotes 离线数据身份验证中涉及的记录数。

在您解析时,您将找到所需的数据。如果您不确定如何解析,请尝试复制十六进制数据here