使用位于HSM上的私钥对数据进行签名和解密

时间:2014-09-08 10:50:50

标签: encryption digital-signature cryptoapi rsacryptoserviceprovider hsm

我有一项签署和解密数据的任务,但私钥位于HSM(Luna SA,/ Safenet)。我安装了所有客户端软件并将Luna SA CSP连接到测试服务器。

使用提供的PKCS#11功能,我可以在HSM上列出并导出公共密钥为PCCERT_CONTEXTCertCreateCertificateContext)。当我尝试获取私钥(使用CryptoAPI函数CryptAcquireCertificatePrivateKey)时,收到错误代码CRYPT_E_NO_KEY_PROPERTY

我可能错过了证书数据和CSP / HSM之间的链接。有没有人做过类似的事情,可以提供任何提示?

修改


我成功地从位于HSM上的所有密钥创建了CER文件。 当我知道使用signtool.exethe one that ships with Microsoft Plattform SDK)时,我可以使用HSM上的密钥签署一个dll(工具向导让我选择密钥容器,密钥规范,......)。我尝试使用工具显示的信息并设置私钥

bool LinkPrivateKey(PCCERT_CONTEXT cert)
{
    CRYPT_KEY_PROV_INFO cryptKeyProvInfo;
    memset(&cryptKeyProvInfo, 0, sizeof(cryptKeyProvInfo));
    cryptKeyProvInfo.pwszContainerName = L"MSS";
    cryptKeyProvInfo.pwszProvName = L"Luna Cryptographic Services for Microsoft Windows";
    cryptKeyProvInfo.dwProvType = PROV_RSA_FULL;
    cryptKeyProvInfo.dwFlags = CRYPT_MACHINE_KEYSET; // CERT_SET_KEY_CONTEXT_PROP_ID | CERT_SET_KEY_PROV_HANDLE_PROP_ID;
    cryptKeyProvInfo.cProvParam = 0;
    cryptKeyProvInfo.dwKeySpec = AT_SIGNATURE;

    return CertSetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, 0, &cryptKeyProvInfo) != FALSE;
}

但CryptAcquirePrivateKey仍然给我同样的错误。我相信我在这里只缺少一点,因为signtool能够访问私钥

enter image description here

EDIT2


screnshot显示KEYEXCHANGE,但我选择了SIGNATURE

EDIT3


我稍微更改了LinkPrivateKey功能,现在可以正常工作

bool LinkPrivateKey(PCCERT_CONTEXT cert)
{
    CRYPT_KEY_PROV_INFO cryptKeyProvInfo;
    memset(&cryptKeyProvInfo, 0, sizeof(cryptKeyProvInfo));
    cryptKeyProvInfo.pwszContainerName = L"MSS";
    cryptKeyProvInfo.pwszProvName = L"Luna Cryptographic Services for Microsoft Windows";
    cryptKeyProvInfo.dwProvType = PROV_RSA_FULL;
    cryptKeyProvInfo.dwFlags = 1; // CERT_SET_KEY_CONTEXT_PROP_ID | CERT_SET_KEY_PROV_HANDLE_PROP_ID;
    cryptKeyProvInfo.dwKeySpec = AT_SIGNATURE;

    return CertSetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, 0, &cryptKeyProvInfo) != FALSE;
}

2 个答案:

答案 0 :(得分:1)

我对Luna没有任何经验,但这对nCiper HSM来说效果很好:

certutil -repairstore -csp "nCipher Enhanced Cryptographic Provider" My <serial number of certificate>

其中“nCipher Enhanced Cryptographic Provider”是HSM附带的CSP的名称。

可以使用以下命令获取证书的序列号:

certutil -store My

它将在Local_Machine \ My store中打印所有证书。序列号将介于======和================ Certificate 5 ================之间。它还将解析有关序列号,主题等证书的信息,并将运行加密/解密测试以验证证书的可用性。

修复绑定后,可以使用此(第二个)命令验证它是否正常。不要被第一个命令的输出所迷惑,我从未见过除了成功之外的其他任何事情。

您可以找到有关certutil here的使用的更多信息。

答案 1 :(得分:1)

如我的帖子所述,我可以使用

链接私钥

我稍微更改了LinkPrivateKey函数,现在它可以正常工作

bool LinkPrivateKey(PCCERT_CONTEXT cert)
{
    CRYPT_KEY_PROV_INFO cryptKeyProvInfo;
    memset(&cryptKeyProvInfo, 0, sizeof(cryptKeyProvInfo));
    cryptKeyProvInfo.pwszContainerName = L"MSS";
    cryptKeyProvInfo.pwszProvName = L"Luna Cryptographic Services for Microsoft Windows";
    cryptKeyProvInfo.dwProvType = PROV_RSA_FULL;
    cryptKeyProvInfo.dwFlags = 1; // CERT_SET_KEY_CONTEXT_PROP_ID | CERT_SET_KEY_PROV_HANDLE_PROP_ID;
    cryptKeyProvInfo.dwKeySpec = AT_SIGNATURE;

    return CertSetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, 0, &cryptKeyProvInfo) != FALSE;
}

您必须使用服务器上定义的密钥容器替换L"MSS"。 LunSA提供与LunaCSP一起打包的工具keymap.exe以获取容器名称。