我有一项签署和解密数据的任务,但私钥位于HSM(Luna SA,/ Safenet)。我安装了所有客户端软件并将Luna SA CSP连接到测试服务器。
使用提供的PKCS#11功能,我可以在HSM上列出并导出公共密钥为PCCERT_CONTEXT
(CertCreateCertificateContext
)。当我尝试获取私钥(使用CryptoAPI函数CryptAcquireCertificatePrivateKey
)时,收到错误代码CRYPT_E_NO_KEY_PROPERTY
。
我可能错过了证书数据和CSP / HSM之间的链接。有没有人做过类似的事情,可以提供任何提示?
我成功地从位于HSM上的所有密钥创建了CER文件。
当我知道使用signtool.exe
(the 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能够访问私钥
screnshot显示KEYEXCHANGE,但我选择了SIGNATURE
我稍微更改了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;
}
答案 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
以获取容器名称。