首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用pkcs#11从智能卡读取文本文件

用pkcs#11从智能卡读取文本文件
EN

Stack Overflow用户
提问于 2016-02-25 13:25:47
回答 1查看 1.2K关注 0票数 1

我有一个空白智能卡(SLE66CX322P, Cardos 4.3b)和一个读卡器/作家(Gemalto CT 40) )。使用一个软件,我可以初始化卡,生成密钥,证书等。我还可以创建一个简单的ASCII文件与一些文本,将存储在智能卡。我的问题是,如何使用C/C++读取这个ASCII文件的内容?

下面是我到目前为止尝试过的(同时使用Qt):

代码语言:javascript
复制
#ifndef CARDREADER_H
#define CARDREADER_H

#include "cm-pkcs11.h"
#include <QCoreApplication>
#include <QObject>
#include <QtDebug>

class CardReader: public QObject
{
    Q_OBJECT

private:

    CK_RV rv;
    CK_ULONG slotCount;
    CK_SLOT_ID slotIds[10];
    CK_SLOT_ID slotId;
    CK_SESSION_HANDLE session;
    CK_TOKEN_INFO_PTR info;

    void readCard();

public:

    explicit CardReader(QObject *parent = 0);
};

#endif // CARDREADER_H

- cardreader.cpp -cardreader.cpp

代码语言:javascript
复制
#include "cardreader.h"

CardReader::CardReader(QObject *parent) : QObject(parent)
{
    readCard();
}

/***********************************************************************/

void CardReader::readCard()
{
    rv = C_Initialize(NULL_PTR);

    slotCount = 10;
    rv = C_GetSlotList(CK_TRUE, slotIds, &slotCount);
    qWarning() << "Found" << slotCount << "slots";

    if (rv != CKR_OK || slotCount < 1)
    {
        qWarning() << "No slots found -> exit";
        return;
    }

    slotId = slotIds[0];

    rv = C_OpenSession(slotId, CKF_SERIAL_SESSION|CKF_RW_SESSION, NULL_PTR, NULL_PTR, &session);

    if (rv != CKR_OK)
    {
        qWarning() << "Sessions could not be opened -> exit";
        qWarning() << "RV (as hex value) = " << QString("%1").arg(rv, 0, 16);
        return;
    }

    /*********************************************************************/

    CK_OBJECT_CLASS dataClass = CKO_DATA;
    CK_OBJECT_HANDLE handleObject;
    CK_UTF8CHAR label[] = {"MyLabel"};
    CK_ULONG ulCount = 4ul;
    CK_CHAR application[] = {"TestApplication"};
    CK_BYTE dataValue[] = {"MyData"};
    CK_BBOOL valid = CK_TRUE;
    CK_ATTRIBUTE dataTemp[] =
    {
        {CKA_CLASS, &dataClass, sizeof(dataClass)},
        {CKA_VALUE, dataValue, sizeof(dataValue)},
        {CKA_LABEL, label, sizeof(label)-1},
        //{CKA_APPLICATION, application, sizeof(application)}
        {CKA_TOKEN, &valid, sizeof(true)}
    };

    rv = C_FindObjectsInit(session, dataTemp, 0);
    if (rv != CKR_OK)
    {
        qWarning() << "C_FindObjectsInit Error -> exit";
        qWarning() << "C_FindObjectsInit Error" << QString("%1").arg(rv, 0, 16);
        return;
    }


    while (1)
    {
        rv = C_FindObjects(session, &handleObject, 1, &ulCount);
        qWarning() << "C_FindObjects Result =" << QString("%1").arg(rv, 0, 16) << ", count =" << ulCount;
        if (rv != CKR_OK || ulCount == 0)
            break;

        rv = C_GetAttributeValue(session, handleObject, dataTemp, ulCount);

        if (rv != CKR_OK)
        {
            qWarning() << "C_GetAttributeValue error -> exit";
            qWarning() << "RV (as hex value) = " << QString("%1").arg(rv, 0, 16) << ", count = " << ulCount;
            return;
        }

        qWarning() << (const char *) dataTemp[0].pValue;
        qWarning() << (const char *) dataTemp[1].pValue;
        qWarning() << (const char *) dataTemp[2].pValue;
        qWarning() << (const char *) dataTemp[3].pValue;
    }
}

- main.cpp

代码语言:javascript
复制
#include "cardreader.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    CardReader c;

    return a.exec();
}

结果是这个块

代码语言:javascript
复制
        qWarning() << (const char *) dataTemp[0].pValue;
        qWarning() << (const char *) dataTemp[1].pValue;
        qWarning() << (const char *) dataTemp[2].pValue;
        qWarning() << (const char *) dataTemp[3].pValue;

在控制台中打印四次,但始终使用MyLabelMyData作为结果,这是我在CardReader::readCard()开头指定的。当然,智能卡上的文本文件的内容是不同的,但遗憾的是输出中没有显示出来。

我还想提到,我也能够使用C_CreateObject()函数。这在智能卡上生成了第二个ASCII文件。但是第二个文件我也不能用我的代码读出。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-02-27 22:18:46

最有可能的原因:

  • ulCount变量被C_FindObjects()覆盖到1
  • 在调用4之前,您需要再次将其重新分配给C_GetAttributeValue
  • 这样,代码只读取模板中的第一个属性。

一些额外的(随机)注释:

  • 由于不调用C_Login(),所以只能查看/访问公共对象(设置为CKA_PRIVATE的对象为您隐藏)。
  • ulCount的零参数会导致代码枚举所有令牌对象--您可能希望CKA_CLASSCKA_LABEL筛选器有效。
  • 我建议不要在C_FindObjectsInit()C_GetAttributeValue()中使用相同的模板
  • 您的dataValue缓冲区非常小--您确定值是否合适吗?

祝好运!

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35628599

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档