【问题标题】:How to read details of the X.509 certificate stored on usb token?如何读取存储在 USB 令牌上的 X.509 证书的详细信息?
【发布时间】:2013-04-26 07:33:32
【问题描述】:

我正在为我的应用程序使用 SafeNet 的 iKey usb 令牌。

我的应用程序是 C++(win32 应用程序),我正在通过其 SDK 的 PKCS 接口 (pkcs11.h) 访问令牌的功能。

到目前为止,我已经能够成功地完成以下工作:生成公钥/私钥对、加密/解密、签名/验证、读取存储在令牌中的对象的属性。

但主要问题是:将 X.509 证书导入令牌后(使用 iKey 令牌实用程序),我无法在 C++ 应用程序中读取证书详细信息,因为我需要这些来知道哪个用户正在使用我的应用程序,即用户身份。但是,通过令牌驱动程序附带的“iKey 令牌实用程序”,可以查看证书详细信息。我在任何地方都找不到该实用程序的源代码,而且 pkcs11.h 库没有任何与读取证书详细信息相关的功能。对我来说,读取证书的公钥值(不是它的句柄)会很有帮助。

我尝试使用 PKCS 读取令牌内证书对象的属性,但似乎它给了我以某种格式编码的值。

我通过互联网彻底查看了 SDK 文档,但找不到问题的答案:

  • 如何在 C++ 中使用 PKCS 从 USB 安全令牌中读取 X509 证书详细信息?

如果有任何解决此问题的提示,我将不胜感激,谢谢...

【问题讨论】:

    标签: c++ x509certificate pkcs#11


    【解决方案1】:

    根据 PKCS#11,X509 证书是某种存储对象,其数据类(CKA_CLASS 属性)等于 CKO_CERTIFICATE
    如果要从令牌中检索证书对象,只需使用 C_GetAttributeValue 函数即可。
    在执行此操作之前,您可能需要查找存储在您的令牌中的所有 x.509 证书:

    CK_BBOOL _true = CK_TRUE;
    CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
    CK_CERTIFICATE_TYPE certType = CKC_X_509_ATTR_CERT;
    CK_ATTRIBUTE certificateSearchTemplate[] = {
        {CKA_CLASS, &certClass, sizeof(dataClass)},
        {CKA_CERTIFICATE_TYPE, &certType, sizeof(certType)},
        {CKA_TOKEN, &_true, sizeof(_true)}
    };
    
    CK_OBJECT_HANDLE hObject;
    CK_ULONG ulObjectCount;
    CK_RV rv = C_FindObjectsInit(hSession, certificateSearchTemplate, 3);
    assert(rv == CKR_OK);
    while (1) {
       rv = C_FindObjects(hSession, &hObject, 1, &ulObjectCount);
       if (rv != CKR_OK || ulObjectCount == 0)
          break;
       //hObject is handle of a x.509 certificate, so you can fetch your desired attributes from it using C_GetAttributeValue
      getCertificateAttributes(hObject);
    }
    rv = C_FindObjectsFinal(hSession);
    assert(rv == CKR_OK);
    

    getCertificateAttributes 函数中,您可以获得所需的证书属性:

    void getCertificateAttributes(CK_OBJECT_HANDLE hCert)
    {
       CK_ATTRIBUTE pTemplate[] = {
          //List your desired attributes here
       };
       ...
       CK_RV rv = C_GetAttributeValue(hSession, hCert, &pTemplate, pTemplateLen);
       if (rv == CKR_OK) {
          //here you have your desired certificate attributes
       }
    }
    

    【讨论】:

    • 感谢 Ehsan 的回答。从理论上讲,这应该是正确的方法。正如我所提到的,我尝试读取证书的所有属性,但它没有给我所需的值。例如,它没有保存 pub 的属性。键,但它有 CKA_LABEL 属性,其值是 ok 的。如果我可以提取酒吧,我的问题将得到解决。键值。
    • 在我的例子中,CKA_VALUE 属性包含最大的数据,超过 800 个字节,但它无法识别为证书详细信息,我猜证书详细信息(包括 pub.key)以某种编码存储在这些字节中,在这种情况下,问题仍然在于如何解码这些字节......
    • 您确定证书正确存储在您的令牌中吗?你是如何将它存储在你的令牌上的?有关 X.509 证书对象属性的更多详细信息,您可以参考 PKCS#11 规范中的表 24:ftp.rsasecurity.com/pub/pkcs/pkcs-11/v2-30/pkcs-11v2-30b-d6.pdf
    • 是的,证书肯定是正确存储在token上的,因为可以查看cert.供应商提供的实用程序信息。我认为属性值是以 DER 编码存储的,应该将它们从 DER 转换为人类可读的形式。
    【解决方案2】:

    除了 PKCS#11 库,Microsoft CryptoAPI(mscapi.dll) 也可用于检索证书详细信息。但是,MSCAPI 也在内部使用 PKCS 与 USB 令牌进行交互。因此,应该有一些方法可以解决这个问题,单独使用 PKCS 库而不使用 MSCAPI。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-07-18
      • 1970-01-01
      • 1970-01-01
      • 2011-12-13
      • 1970-01-01
      • 2021-02-15
      • 1970-01-01
      • 2012-07-06
      相关资源
      最近更新 更多