2

我的任务是签署和解密数据,但私钥位于 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.exeMicrosoft 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 能够访问私钥

在此处输入图像描述

编辑2


截图显示 KEYEXCHANGE 但我选择了 SIGNATURE

编辑3


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;
}
4

2 回答 2

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 商店中的所有证书。序列号将在 ====== 之类的一堆之间================ Certificate 5 ================。它还将解析有关证书的信息,如序列号、主题等,并将运行加密/解密测试以验证证书的可用性。

修复绑定后,您可以使用此(第二个)命令来验证它是否运行良好。不要被第一个命令的输出所迷惑,我从来没有见过它除了成功之外的任何东西。

您可以在此处找到有关 certutil 用法的更多信息。

于 2014-09-08T12:21:35.870 回答
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 提供了keymap.exe与 LunaCSP 一起安装的工具来获取容器名称。

于 2014-09-08T15:43:20.877 回答