如何读取智能卡上的用户数据?

时间:2014-12-26 19:46:44

标签: c++ smartcard javacard winscard

首先,我使用智能卡仍然相对较新,我不知道数据是如何存储的,以及哪些数据受智能卡保护。

我试图读取受PIN保护的学生识别智能卡。我使用默认的Windows智能卡库(winscard.lib)在C ++中编程。

我已成功读取ATR标头但据我所知,ATR标头包含有关如何与阅读器通信的信息,而不是用户信息。

我已尝试从卡中读取二进制文件,但APDU始终返回6E 00,表示" Class不受支持"或"错误的指示"。这是代码:

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%08X\n",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 };

可能有什么不对?我是否需要先验证卡才能读取二进制文件?读取二进制权限函数来读取学生ID等基本数据吗?

4 个答案:

答案 0 :(得分:2)

如果没有卡片上学生申请的说明,这是一个漫长而无聊的过程。 假设您需要知道卡上的文件系统(而不是Java卡),在哪个文件中存储用户数据,以便您可以在发出之前 SELECT 相应的文件。 READ BINARY pr READ RECORD 如果是面向记录的文件。您可以尝试通过反复试验找到正确的文件ID,但是......请注意,在智能卡上,访问条件的粒度非常精细,因此可能存在无需任何身份验证即可读取的文件,以及另一个极端情况是,在建立了通过安全消息传递(加密和MAC保护的命令和/或响应)使用的安全通道之后,可能只有文件可读。

答案 1 :(得分:0)

我可以想到卡片返回6E00的两个原因。

  1. 当前选定的应用程序是卡片管理器或除您要使用的应用程序之外的任何其他applet。您可以在发送READ命令之前尝试执行SELECT AID命令。但是,您应该知道要选择的applet的实例AID。

  2. 您尝试读取的文件受安全消息传递的保护,您的APDU命令应加密/ MAC,这会将CLA字节更改为“0C”。但是,您需要先建立安全通道才能执行此操作。

  3. 就像@guidot所说,如果没有规范,这将非常困难。

答案 2 :(得分:0)

首先,正如@guidot提到它的无聊过程。不仅你有关于javacards的完整信息,而且你应该知道如何破解智能卡,因为你没有任何卡供应商规范,可能他们在卡上使用你应该知道密钥的安全性。

但是根据ISO 7816-4 0x6E00表示&#34; Class不受支持&#34;对于您的信息。您可以在here中查看完整的APDU响应列表。

类(CLA)字节通常是0x000xA00xC00xF0,有时会被0x0C屏蔽,表示某些卡上的安全消息传递

要访问applet防火墙内的数据,您应该选择当JCRE(Java Card运行时环境)收到其数据与applet的AID匹配的选择APDU时,会发生applet和applet选择。 如果安装了安全域,那么您应该拥有这些安全密钥才能成功选择小程序。

要获得与读卡器通信的APDU命令列表,请选中this link

有很多关于用C ++编写智能卡库的信息here,它使用WinSCard.dll与读者进行通信。

同样this link是关于java卡中的文件系统结构,如果applet将其数据存储在文件中,这将非常有用。

this link是在javacard中选择文件的示例。

如果您想进一步了解Java卡小程序的实施,here是如何实施Java卡小程序的指南。 请注意,不要忘记阅读最重要的现有文档,如全球平台和ISO 7816。

答案 3 :(得分:0)

正如Chooch所说:在JAVA卡中, 你应该遵循AID选择 2.既然您是读者二进制文件,请选择二进制EF 2a)。由于你使用的是P1 00,我希望你已经选择了特定的EF。 注意:即使我觉得你的命令在ISO 7816 / ISO 14443智能卡中读取二进制数据是错误的。

其他AS ISO 7816 4:

读者二进制文件应该是: CLA INS 00 BO P1 - 短文件ID:MSB应该是1:你的SID是3:它应该是:83 P2 - 应该是偏移/开始字节:例如:从0表示:00如果它在10:0A之间 Le - 应该是您想要读取的字节数:例如,20个字节表示:14

所以命令应该是:00 B0 83 14 0A:就是这样。无需更多字节即可读取二进制文件。如果你已经选择了EF文件Insted of 83,你可以给00: 注意:这是认为您没有安全条件。如果你有安全条件,你必须在阅读之前满足这一要求。