Java 使用 APDU 命令获取卡片的一些信息
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/40663460/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Use APDU commands to get some information for a card
提问by mareyes
I have a terminal that has its own API to stablish and send commands between chip and terminal, there is a function that transmits the APDU command and returns the answer in a byte array.
我有一个终端,它有自己的 API 来在芯片和终端之间建立和发送命令,有一个函数可以传输 APDU 命令并以字节数组形式返回答案。
For example, if a want to read the tag 5A (Application PAN), I send the following command:
例如,如果要读取标签 5A(应用程序 PAN),我发送以下命令:
byte[] byteArrayAPDU = new byte[]{(byte)0x00, (byte)0xCA, (byte)0x00, (byte)0x5A};
int nResult = SmartCardInterface.transmit(nCardHandle, byteArrayAPDU, byteArrayResponse);
The variable byteArrayResponse
gets the response to the APDU command.
该变量byteArrayResponse
获取对 APDU 命令的响应。
When I translate the value of byteArrayAPDU
to a string of hexadecimal digits, this gives me: 00 CA 00 5A
. And the response to that command is 6E 00
(class not supported).
当我将 的值byteArrayAPDU
转换为一串十六进制数字时,这给了我:00 CA 00 5A
. 对该命令的响应是6E 00
(不支持类)。
My device works with ISO 7816 as technical specifications. Is the way in which I am sending APDU commands correct? I ask this because I have read that an APDU command must have 5 values at least, but I don't know what to send in the fifth parameter. I don't know what the lenght of the response is.
我的设备使用 ISO 7816 作为技术规范。我发送 APDU 命令的方式是否正确?我问这个是因为我读过一个 APDU 命令必须至少有 5 个值,但我不知道在第五个参数中发送什么。我不知道响应的长度是多少。
Can you give an example of how to get the tag 5A or something else in APDU commands?
您能否举例说明如何在 APDU 命令中获取标签 5A 或其他内容?
If the command where correct, in place of where I see 6E 00
at the moment, would I see the information as plain text when cast to a string?
如果命令正确,而不是我目前看到的6E 00
位置,那么在转换为字符串时,我是否会将信息视为纯文本?
回答by Michael Roland
The input and output values that you showed in your question suggest that your use of the method transceive()
is correct, i.e. the second argument is a command APDU and the third argument is filled with the response APDU:
您在问题中显示的输入和输出值表明您使用该方法transceive()
是正确的,即第二个参数是命令 APDU,第三个参数填充响应 APDU:
resultCode = SmartCardInterface.transmit(cardHandle, commandAPDU, ResponseAPDU);
Your question regarding the format and validity of APDU commands is rather broad. In general, the format of APDUs and a basic set of commands is defined in ISO/IEC 7816-4. Since you tagged the question with emvand mention the application primary account number, you are probably interacting with some form of EMV payment card (e.g. a credit or debit card from one of the major schemes). In that case, you would probably want to study the various specifications for EMV payment systems which define the data structures and application-specific commands for those cards.
您关于 APDU 命令的格式和有效性的问题相当广泛。一般来说,APDU 的格式和基本命令集在 ISO/IEC 7816-4 中定义。由于您使用emv标记了问题并提到了应用程序主帐号,因此您可能正在与某种形式的 EMV 支付卡(例如来自主要计划之一的信用卡或借记卡)进行交互。在这种情况下,您可能想要研究 EMV 支付系统的各种规范,这些规范定义了这些卡的数据结构和特定于应用程序的命令。
Regarding your specific questions:
关于您的具体问题:
Do APDUs always consist of at least 5 bytes?
APDU 是否总是至少包含 5 个字节?
No, certainly not. Command APDUs consist of at least 4 bytes (the header bytes). These are
不,当然不是。命令 APDU 至少包含 4 个字节(报头字节)。这些是
+-----+-----+-----+-----+ | CLA | INS | P1 | P2 | +-----+-----+-----+-----+
Such a 4-byte APDU is called "case 1". This means that the command APDU does not contain a data field sent to the card and that the card is not expected to generate a response data field. So the response APDU is expected to only contain a response status word:
这种 4 字节的 APDU 称为“情况 1”。这意味着命令 APDU 不包含发送到卡的数据字段,并且不希望卡生成响应数据字段。所以响应 APDU 预计只包含一个响应状态字:
+-----+-----+ | SW1 | SW2 | +-----+-----+
What is the 5th byte of a command APDU?
命令 APDU 的第 5 个字节是什么?
The 5th byte is a length field (or part of a length field in case of extended length APDUs, which I won't further explain in this post). Depending on the case, this length field may have two meanings:
第 5 个字节是长度字段(或者在扩展长度 APDU 的情况下是长度字段的一部分,我不会在这篇文章中进一步解释)。根据情况,这个长度字段可能有两种含义:
If the command APDU does not have a data field, that length field indicates the expected length (Ne) of the response data field:
+-----+-----+-----+-----+-----+ | CLA | INS | P1 | P2 | Le | +-----+-----+-----+-----+-----+
- Le = 0x01 .. 0xFF: This means that the expected response data length Ne is 1, 2, ... 255 bytes (i.e. exactly the value of Le).
- Le = 0x00: This means that the expected response data length Ne is 256 bytes. This is typically used to instruct the card to give you as much bytes as it has available (up to 256 bytes). So even if Le is set to 0x00, you won't always get exactly 256 bytes from the card.
If the command APDU itself has a data field, that length field indicates the length (Nc) of the command data field:
+-----+-----+-----+-----+-----+-----------------+ | CLA | INS | P1 | P2 | Lc | DATA (Nc bytes) | +-----+-----+-----+-----+-----+-----------------+
- Lc = 0x01 .. 0xFF: This means that the command data length Nc is 1, 2, ... 255 bytes (i.e. exactly the value of Lc).
- Lc = 0x00: This is used to indicate an extended length APDU.
If there is a command data field and the command is expected to generate response data, that command APDU may again be followed by an Le field:
+-----+-----+-----+-----+-----+-----------------+-----+ | CLA | INS | P1 | P2 | Lc | DATA (Nc bytes) | Le | +-----+-----+-----+-----+-----+-----------------+-----+
如果命令 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 bytes) | +-----+-----+-----+-----+-----+-----------------+
- Lc = 0x01 .. 0xFF:这意味着命令数据长度 Nc 为 1、2、... 255 个字节(即正好是 Lc 的值)。
- Lc = 0x00:这用于指示扩展长度的 APDU。
如果有一个命令数据字段并且该命令预计会生成响应数据,那么该命令 APDU 可能会再次跟随一个 Le 字段:
+-----+-----+-----+-----+-----+-----------------+-----+ | CLA | INS | P1 | P2 | Lc | DATA (Nc bytes) | Le | +-----+-----+-----+-----+-----+-----------------+-----+
Is the command 00 CA 00 5A
correct?
命令00 CA 00 5A
正确吗?
Probably not, for several reasons:
可能不会,有以下几个原因:
Since you expect the card to deliver a response data field (i.e. the data object 0x5A), you need to specify an Le field. Hence, a valid format would be
+------+------+------+------+------+ | CLA | INS | P1 | P2 | Le | +------+------+------+------+------+ | 0x00 | 0xCA | 0x00 | 0x5A | 0x00 | +------+------+------+------+------+
You receive the status word
6E 00
in response to the command. The meaning of this status word is "class not supported". This indicates that commands with the CLA byte set to 0x00 are not supported in the current state. With some cards this also simply means that this combination of CLA and INS (00 CA
) is not supported, eventhough this contradicts the definition in ISO/IEC 7816-4.Overall, you can assume that your card does not support this command in its current execution state.
Assuming you are interacting with an EMV payment card, you typically need to select an application first. Your question does not indicate if you do this already, so I assume, you don't do this right now. Selecting an application is done by sending a SELECT (by AID) command:
+------+------+------+------+------+-----------------+------+ | CLA | INS | P1 | P2 | Le | DATA | Le | +------+------+------+------+------+-----------------+------+ | 0x00 | 0xA4 | 0x04 | 0x00 | 0xXX | Application AID | 0x00 | +------+------+------+------+------+-----------------+------+
The value of the application AID, of course, depends on the card application and may be obtained by following the discovery procedures defined in the EMV specifications.
Even after application selection, the GET DATA APDU command for EMV applications is defined in the proprietary class. Consequently, the CLA byte must be set to 0x80:
+------+------+------+------+------+ | CLA | INS | P1 | P2 | Le | +------+------+------+------+------+ | 0x80 | 0xCA | 0x00 | 0x5A | 0x00 | +------+------+------+------+------+
Finally, even then, I'm not aware of any schemes where cards would allow you to retrieve the PAN through a GET DATA command. Usually, the PAN is only accessible through file/record based access. Since you did not reveal the specific type/brand of your card, it's impossible to tell what your card may or may not actually support.
由于您希望卡片传递响应数据字段(即数据对象 0x5A),因此您需要指定一个 Le 字段。因此,有效的格式将是
+------+------+------+------+------+ | CLA | INS | P1 | P2 | Le | +------+------+------+------+------+ | 0x00 | 0xCA | 0x00 | 0x5A | 0x00 | +------+------+------+------+------+
您收到
6E 00
响应命令的状态字。此状态字的含义是“不支持类”。这表示当前状态不支持 CLA 字节设置为 0x00 的命令。对于某些卡,这也仅仅意味着00 CA
不支持CLA 和 INS ( ) 的这种组合,尽管这与 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。由于您没有透露卡的具体类型/品牌,因此无法确定您的卡实际上支持或不支持什么。
回答by iso8583.info support
At Start
开始时
Standard ISO 7816 includes several parts. When terminal device vendors noticed about ISO 7816 they just confirm that the common Physical characteristics (Part 1), Dimension and Contacts (Part 2) and Transmission protocol (Part 3) were applied to the device reader.
标准 ISO 7816 包括几个部分。当终端设备供应商注意到 ISO 7816 时,他们只是确认通用物理特性(第 1 部分)、尺寸和接触(第 2 部分)和传输协议(第 3 部分)已应用于设备阅读器。
APDU commands and responses defined in ISO 7816 Part 4 (and few other parts also) are generic definition and might not fully supported by your smartcard.
ISO 7816 第 4 部分(以及少数其他部分)中定义的 APDU 命令和响应是通用定义,您的智能卡可能不完全支持。
You need to learn about the card-terminal interaction layers related to your card type:
您需要了解与您的卡类型相关的卡端交互层:
- EMV is the customized version of ISO 7816 for Payment cards.
- Global Card Brands used own customized specifications based on EMV and ISO 7816. For sample Amex "AEIPS", Diners "D-PAS", MasterCard "M/Chip", Visa "VIS", etc. They are almost the same with small differences related to the supported Commands, flows and list of Tags.
- EMV 是支付卡 ISO 7816 的定制版本。
- Global Card Brands 使用基于 EMV 和 ISO 7816 的自己定制的规范。例如 Amex“AEIPS”、Diners“D-PAS”、MasterCard“M/Chip”、Visa“VIS”等,它们几乎相同,但差异很小与支持的命令、流程和标签列表相关。
Unfortunately most of payment cards are not supposed to return Tag 0x5A value with GET DATAAPDU command. Usually you need to follow payment procedure. At least SELECTcard application and READTag Values from SFIcard records.
不幸的是,大多数支付卡不应该使用GET DATAAPDU 命令返回标签 0x5A 值。通常您需要遵循付款程序。至少从SFI卡记录中选择卡应用程序和读取标签值。
According to EMV GET DATAP1 P2 values should be used for Tags 0x9F36, 0x9F13, 0x9F17, or 0x9F4F.
根据 EMV GET DATAP1 P2 值应用于标签 0x9F36、0x9F13、0x9F17 或 0x9F4F。
Answering your questions:
回答您的问题:
What to send in the fifth parameter? What is the length of the response?
在第五个参数中发送什么?响应的长度是多少?
Fifth byte known as "Le" - Length of Expected Data. You can try to use Le = "00". If APDU command supported by card you may get SW1SW2 as 0x"6Cxx" where xxis the hexadecimal length of the requested data. When you can repeat same command with correct Le value.
称为“Le”的第五个字节 - 预期数据的长度。您可以尝试使用 Le=" 00"。如果卡支持 APDU 命令,您可能会得到 SW1SW2 为 0x" 6Cxx",其中xx是所请求数据的十六进制长度。当您可以使用正确的 Le 值重复相同的命令时。
For sample, to read PIN Counter
例如,读取 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)
If the command where satisfactory in place of see 6E 00 at the moment of cast the answer to string I would see the information as plain text?
如果在将答案转换为字符串的那一刻看到 6E 00 的命令令人满意,我会将信息视为纯文本吗?
APDU commands and responses used BYTE encoding. According to provided terminal API example you will get Array of Bytes.
APDU 命令和响应使用 BYTE 编码。根据提供的终端 API 示例,您将获得字节数组。
As developer you can transform bytes into desired format or use it as-is. Please keep in mind that according to EMV specifications the formats of Tags data can be variable:
作为开发人员,您可以将字节转换为所需的格式或按原样使用。请记住,根据 EMV 规范,标签数据的格式可以是可变的:
- HEX(or binary) for sample for numeric Tags like amounts;
- BCDfor sample for date/time or some numbers like currency. PAN also BCD encoder;
- Strings in different charsets (ASCII, Unicode, ...) for sample for Cardholder Name, Application Name.
- etc.
- HEX(或binary)用于数字标签(如金额)的样本;
- BCD用于日期/时间或某些数字(如货币)的样本。PAN 也 BCD 编码器;
- 持卡人姓名、应用程序名称示例的不同字符集(ASCII、Unicode 等)中的字符串。
- 等等。
Tag 0x5A - Application Primary Account Number (PAN) encoded as BCD and can be padded with 0xF in case odd PAN length.
标记 0x5A - 编码为 BCD 的应用程序主帐号 (PAN),如果 PAN 长度为奇数,则可以用 0xF 填充。
回答by Adarsh Nanu
Just answering to how READ your specific tag data since APDU and application State behavior is already answered. After you SELECT application, you can initiate a GET PROCESSING OPTIONS. This is the actual start of the transaction. Here you will be returned a tag named AFL (application file locator). You need to parse this element and do multiple READ RECORDS till you find the data. AFL is a set of four byte data( If you have two sets of SFI, there will be eight byte data).
只是回答如何读取您的特定标签数据,因为 APDU 和应用程序状态行为已经得到回答。在您选择应用程序后,您可以启动一个 GET PROCESSING OPTIONS。这是交易的实际开始。在这里,您将返回一个名为 AFL(应用程序文件定位器)的标签。您需要解析此元素并执行多个读取记录,直到找到数据。AFL是一组四字节数据(如果你有两组SFI,就会有八字节数据)。
- First byte denote the SFI(5 most significant bytes is the input to P2 of READ RECORD). Second byte denotes the first record to read( input to P1 of READ RECORD). Third byte denotes the last record to read.( you need to loop READ RECORD this many times) The fourth byte donotes the number of records involved in offline data authentication.
- 第一个字节表示 SFI(5 个最高有效字节是 READ RECORD 的 P2 的输入)。第二个字节表示要读取的第一条记录(输入到 READ RECORD 的 P1)。第三个字节表示要读取的最后一条记录。(需要多次循环READ RECORD) 第四个字节表示离线数据认证涉及的记录数。
As you parse through, you will find the your required data. In case you are not sure how to parse, copy the hex data an try it here
当您解析时,您将找到所需的数据。如果您不确定如何解析,请复制十六进制数据并在此处尝试