当前位置: 首页 > 知识库问答 >
问题:

在PKCS#11中签名证书

百里飞捷
2023-03-14

为了在OpenSSL中签名证书,我使用x509_sign()函数,向它提供一个请求(作为x509_req*)、一个签名密钥和一个摘要。

现在我有我的签名密钥存储在HSM中,所以我无法提取它来签名证书。不幸的是,PKCS#11没有提供x509_sign()的等价物。它只有c_sign()/C_SignUpdate()/C_SignFinal()系列函数,这些函数对原始数据进行操作,而不是对证书进行操作。

有人能帮助我使用示例C/C++代码如何使用PKCS#11签署一个用OpenSSL创建的证书吗?

共有1个答案

贡斌
2023-03-14

下面的代码在HSM中为给定的X509*结构签名。为了清楚起见,省略了错误处理。

void signCertInHsm(X509* x509, unsigned long pkcs11SigningAlgo, CK_FUNCTION_LIST_PTR p11, CK_SESSION_HANDLE p11session, CK_OBJECT_HANDLE pkcs11PrivKeyHandle)
{
    x509->cert_info->enc.modified = 1;

    // set signature algorithm in the certificate
    if (x509->cert_info->signature)
    {
        const int signingAlgoNid = pkcs11SignatureAlgorithmToNid(pkcs11SigningAlgo);
        X509_ALGOR_set0(x509->cert_info->signature, OBJ_nid2obj(signingAlgoNid), V_ASN1_NULL, NULL);
    }
    if (x509->sig_alg)
    {
        const int signingAlgoNid = pkcs11SignatureAlgorithmToNid(pkcs11SigningAlgo);
        X509_ALGOR_set0(x509->sig_alg, OBJ_nid2obj(signingAlgoNid), V_ASN1_NULL, NULL);
    }

    // DER-encode certificate
    unsigned char *certDerBuf = NULL;
    const size_t certDerLen = ASN1_item_i2d((ASN1_VALUE*)x509->cert_info, &certDerBuf, ASN1_ITEM_rptr(X509_CINF));

    CK_MECHANISM mechanism = { pkcs11SigningAlgo, NULL_PTR, 0 };
    p11->C_SignInit(p11session, &mechanism, pkcs11PrivKeyHandle);

    // determine signature size
    CK_ULONG signatureSize = 0;
    p11->C_Sign(p11session, certDerBuf, certDerLen, NULL, &signatureSize);

    // sign
    if (x509->signature->data)
        OPENSSL_free(x509->signature->data);
    x509->signature->data = (unsigned char*)OPENSSL_malloc(signatureSize);
    x509->signature->length = signatureSize;
    p11->C_Sign(p11session, certDerBuf, certDerLen, x509->signature->data, &signatureSize);

    x509->signature->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
    x509->signature->flags|=ASN1_STRING_FLAG_BITS_LEFT;

    OPENSSL_free(certDerBuf);
}

int pkcs11SignatureAlgorithmToNid(unsigned long algo)
{
    switch(algo)
    {
    case CKM_SHA1_RSA_PKCS: return NID_sha1WithRSAEncryption;
    case CKM_SHA256_RSA_PKCS: return NID_sha256WithRSAEncryption;
    //... add more mappings that your app supports
    default: throw std::invalid_argument("Not supported signature algorithm");
    }
}
 类似资料:
  • 我试图实现PDFS的签名验证。这是一个很大的主题,所以我一步一步地进行,首先,我试图在我自己签名的PDF中实际返回一个正值,使用当前Acrobat的所有默认值--对于摘要,应该是SHA256和PKCS7分离签名。因此,我破解了openssl,通过读取PDF中给出的字节范围并调用函数,我得到了一个哈希值来进行比较。因此,现在我需要读取证书数据等,并使用函数。这个看起来就是我想要的: 如文档中所示。除

  • 遵循http://itextpdf.com/book/digitalsignatures中的“使用智能卡和PKCS#11签名文档”主题并创建与所提供的代码示例类似的代码示例后,签名的文件签名在Adobe Reader中无效,签名外观具有不可否认证书的名称(即eID所有者的名称),但在Adobe Reader的签名面板中显示: 我使用的是金雅拓PinPad和葡萄牙语eID与eID中间件软件一起安装,

  • 我能够成功提取PKCS#7容器数据,并使用以下代码验证数据类型代码值是否为: 然而,我现在已经到了一个我被卡住的地步。如何从PKCS#7有效载荷获取X.509证书数据?我可以看到数据结构应该包含证书链数据。它的数据类型是,我想一旦我在内存中获得X.509证书数据,我就可以找到使用OpenSSL的方法的代码。我只是不知道怎么做那部分。 我找到了这个关于在OSX/IOS上验证收据的资源,它涉及到许多相

  • 问题内容: 在Java中需要有关加密例程的帮助。 给定PKCS#7签名,我想针对受信任的存储验证它包含的所有证书。我假设签名中包含的所有证书均以正确的顺序形成有效的证书路径(或链,无论如何),因此 最上面的(#0)是签名证书; 下一个(#1)是中间证书,用于签署#0; 下一个(#2)是另一个中间证书,用于签署#1; 等等。 最后一个证书(#N)由CA签名。 到目前为止,这是我设法破解的: 所以问题

  • 使用 PIV 和 PKCS#11 验证 SSH(客户端) Yubikey 最酷的特性之一就是通过 PKCS#11 来验证 SSH。 把私钥存储在 Yubikey 上,无论在何时,当它被访问后都可以反馈你的操作。 除了常见的远程登录,所有通过 SSH 连接的操作(比如使用远程 git 服务器(比如 Github))都可以触发这一行为。这是客户端的保护手段,用来防止在未授权的情况下获取到 SSH 私钥