我正在尝试使用Objective-C中的PCSC命令读取智能卡。
int count = 17;
unsigned char *get_cplc_command = (unsigned char *)calloc(count, sizeof(unsigned char));
get_cplc_command[1]=-92;
get_cplc_command[2]=4;
get_cplc_command[4]=12;
get_cplc_command[5]=-96;
get_cplc_command[8]=2;
get_cplc_command[9]=67;
get_cplc_command[11]=19;
get_cplc_command[15]=1;
get_cplc_command[16]=1;
receive_length = sizeof(receive_buffer);
ret = SCardTransmit(card,
&sendPCI,
get_cplc_command,
sizeof(get_cplc_command),
NULL,
receive_buffer,
&receive_length);
LOG(@"SCardTransmit 0x%08x", ret);
当我执行上述命令时,我得到6C6B响应。你能帮我解决一下这个问题。
答案 0 :(得分:2)
状态字6CXX
表示命令APDU的Le
字段错误。
引用ISO 7816-3,表14:
由于错误的Le字段而导致进程中止(SW2对Na进行编码,即 确切的可用数据字节数)。在案例1和3中,卡 不应该使用这样的价值。在案例2和4中,卡片应准备好 用P3 = SW2接收相同的命令。
ISO 7816-4,第5.1.3节:
如果SW1设置为' 6C',则中止该过程并且 在发出任何其他命令之前,同样如此 可以使用SW2(可用数据字节的确切数量)作为短Le字段重新发出命令。
(虽然不熟悉Objective-C)我敢打赌SCardTransmit
的第四个参数(即sizeof(get_cplc_command)
)应该是count
而不是sizeof
运算符不会给出已分配数组的大小,而是指向它的指针的大小。
[假设32位架构且sizeof(unsigned char*)
等于4
]:发送的命令不是00A404000CA00000024300130000000101
按预期,而00A40400
被解释为案例1命令(有关命令APDU情况说明,请参见ISO 7816-3,第12.1.2节。)
PS:请考虑检查receive_length
变量是否存在同样的问题。
编辑>关于61XX
状态:
正如@guidot所写,您需要发出GET RESPONSE(另一个命令)以在收到此状态字后立即获取响应数据。
引用ISO 7816-4:
如果SW1设置为' 61',则该过程完成且之前完成 发出任何其他命令,可以发出GET RESPONSE命令 相同的CLA和使用SW2(仍然可用的数据字节数) 短乐场。
上述GET RESPONSE
命令也记录在ISO 7816-4中(参见例如here)。
在您的情况下,APDU交换应该看起来像这样:
> 00A404000CA00000024300130000000101 // SELECT command
< 6121 // SELECT response -- 33 bytes still available
> 00C0000021 // GET RESPONSE command
< XXXX...XX9000 // GET RESPONSE response (33 bytes and a status word)
(您必须拨打SCardTransmit
两次,一次拨打00A404000C...
,然后拨打00C0000021...
。如果重新使用,请记得重置receive_length
变量。 / p>
注意:您可能希望尝试发送00A404000CA0000002430013000000010100
命令APDU(具有Le字段的相同命令并设置为0x00 - 这意味着您在响应数据中最多需要256个字节)。