如何在智能卡上读取用户数据
How to read user data on smart card?
首先,我使用智能卡仍然相对较新,我不知道数据是如何存储的,以及智能卡上保护哪些数据。
我正在尝试读取受PIN保护的学生证智能卡。我一直在C++使用默认的Windows智能卡库(winscard.lib)进行编程。
我已经成功读取了 ATR 标头,但据我所知,ATR 标头包含有关如何与读者通信的信息,而不是用户信息。
我尝试从卡中读取二进制文件,但 APDU 总是返回 6E 00,表示"不支持类"或"指令错误"。这是代码:
switch(dwProtocol)
{
case SCARD_PROTOCOL_T0:
{
pioSendPci = *SCARD_PCI_T0;
break;
}
case SCARD_PROTOCOL_T1:
{
pioSendPci = *SCARD_PCI_T1;
break;
}
default:
{
printf("Detecting protocol failed!");
printf("Press <ENTER> key to terminate!n");
nResponse = getchar();
lRet = SCardReleaseContext(hContext);
return -1;
}
}
lRet = SCardTransmit(hCard,
&pioSendPci,
(LPCBYTE)&cmdRead,
sizeof(cmdRead),
NULL,
(LPBYTE)&recvbuffer,
&atrLen);
printf("APDU return code:n");
printf("=================n");
for(i=0; i<2; i++)
{
printf("%02X ", recvbuffer[i]);
}
printf("n");
if(lRet!=SCARD_S_SUCCESS)
{
printf("Transmission failed! ErrorCode = 0x%08Xn",lRet);
printf("Press <ENTER> key to terminate!n");
nResponse = getchar();
lRet = SCardReleaseContext(hContext);
return -1;
}
其中 cmdRead 如下所示:
BYTE cmdRead[] = { 0x00, 0xB0, 0x00, 0x00, 0x00, 0x00, 0xFF };
可能出了什么问题?我是否需要先验证卡才能读取二进制?读取二进制权限函数是读取学生证等基本数据吗?
卡上没有学生申请的规范,这是一个漫长而无聊的过程。假设您在卡上有一个文件系统(而不是java卡),您需要知道用户数据存储在哪个文件中,以便您可以在发出READ BINARY pr READ RECORD之前选择适当的文件(如果它是一个面向记录的文件)。您可以尝试通过反复试验找到正确的文件 ID,但是...请注意,在智能卡上,访问条件以非常精细的粒度定义,因此可能存在无需任何身份验证即可读取的文件,而在另一个极端,可能存在仅在建立安全通道以通过安全消息传递(加密和 MAC 保护命令和/或响应)使用的安全通道后才能读取的文件。
我可以想到卡返回 6E00 的两个原因。
-
当前选择的应用程序是卡管理器或除您要使用的小程序之外的任何其他小程序。您可以尝试在发送读取命令之前执行 SELECT AID 命令。但是,您应该知道要选择的小程序的实例 AID。
-
您尝试读取的文件受安全消息传递保护,您的 APDU 命令应加密/MACed,例如,这会将 CLA 字节更改为"0C"。但是,您需要先建立安全通道,然后才能执行此操作。
就像@guidot说的,如果没有规范,这将非常困难。
首先,正如@guidot提到的,这是一个无聊的过程。您不仅拥有有关javacard的完整信息,而且还应该知道如何破解智能卡之类的东西,因为您没有任何卡供应商规范,并且可能他们在他们的卡上使用安全性,您应该知道密钥。
但供您参考,根据ISO 7816-4,0x6E00
表示"不支持类"。您可以在此处查看 APDU 响应的完整列表。
类(CLA)字节通常为0x00
、0xA0
、0xC0
或0xF0
,有时用0x0C
屏蔽,表示某些卡上的安全消息传递。
要访问小程序防火墙内的数据,您应该选择当JCRE(Java卡运行时环境)收到数据与小程序的AID匹配的选定APDU时进行小程序和小程序选择。如果安装了安全域,则应拥有这些安全密钥才能成功选择小程序。
要获得与读卡器通信的 APDU 命令列表,请检查此链接。
这里有很多关于在 C++ 中编写智能卡库的信息,它使用 WinSCard.dll 与读者进行通信。
此外,此链接是关于java卡中的文件系统结构,如果小程序将其数据存储在文件中,这将很有用。
这个链接是在javacard中选择文件的示例。
如果你想进一步了解java card applet的实现,这里有一个关于如何实现java card applet的指南。请注意,不要忘记阅读最重要的现有文档,如全球平台和ISO 7816。
正如Chooch所说: 在JAVA卡中,1.您应该遵循AID选择2.由于你是读者二进制文件,选择二进制EF2a)。由于您使用的是 P1 00,我希望您已经选择了特定的 EF。注意:即使我觉得您的命令在ISO 7816/ISO 14443智能卡中读取二进制数据是错误的。
否则作为ISO 7816 4:
读取器二进制文件应为:共轭亚油酸 00 BOP1 - 短文件 ID : MSB 应为 1 : 您的 SID 应为 3 : 应为 :83P2 - 应该是偏移量/起始字节:例如:从0表示:00,如果它在10:0A之间Le - 应该是要读取的字节数:例如 20 字节表示:14
所以命令应该是:00 B0 83 14 0A :就是这样。不需要更多字节来读取二进制文件。如果您已经选择了 EF 文件 Insted of 83,则可以给出 00:注意:这认为您没有安全条件。如果您有安全条件,则必须在阅读本文之前满足该条件。
- C++如何通过用户输入删除列表元素
- 创建一个函数以在输入为负数或零时输出字符串.第一次执行用户定义的函数
- 如何使用用户输入在C++中正确填充2D数组
- C++MySQL C api用户输入行
- 使用用户定义函数的字符串反转
- 用户定义函数中的指针和输入
- 为什么即使使用-cudart-static进行编译,库用户仍然需要链接到cuda运行时
- 如何只允许用户输入正整数
- C++如何计算用户输入的数字中的偶数位数
- 通过for循环使用用户输入填充列表
- 这是我尝试让用户将值输入到数组中.然后将其隐藏为大量的星号
- 在C++中,我如何接受不同于同一行的用户输入
- 当用户超过按钮点击限制时报告
- Visual C++(VS2017)中用户定义的转换不明确
- 如果用户输入无效,如何使用字符串变量-C++重复输入命令
- C++问题:用户认为数字1-100,程序提出问题不超过6次即可得到答案。无法正确
- 当用户键入分隔符时,停止getline()输入
- 通过错误处理,在C++中可靠地获得用户十六进制输入
- RegGetValue在当前用户下找不到名称
- 函数计算用户按下按钮的频率