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

Encryption 使用HSM上的私钥对数据进行签名和解密,encryption,digital-signature,cryptoapi,rsacryptoserviceprovider,hsm,Encryption,Digital Signature,Cryptoapi,Rsacryptoserviceprovider,Hsm,我的任务是对数据进行签名和解密,但私钥位于HSM(Luna SA,/Safenet)上。我安装了所有客户端软件,并将Luna SA CSP连接到测试服务器 使用提供的PKCS#11功能,我能够将HSM上的公钥作为PCCERT#U上下文(CertCreateCertificateContext)列出并导出。当我尝试获取私钥时(使用CryptoAPI函数CryptoAcquireCertificatePrivateKey),我收到一个错误代码CRYPT\u E\u NO\u key\u属性 我可能缺

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

使用提供的PKCS#11功能,我能够将HSM上的公钥作为
PCCERT#U上下文
CertCreateCertificateContext
)列出并导出。当我尝试获取私钥时(使用CryptoAPI函数
CryptoAcquireCertificatePrivateKey
),我收到一个错误代码
CRYPT\u E\u NO\u key\u属性

我可能缺少证书数据和CSP/HSM之间的链接。有没有人做过类似的事情,可以给出一些提示

编辑
我成功地从HSM上的所有密钥创建了CER文件。 当我知道如何使用
signtool.exe
()时,我可以使用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;
}
但是CryptoAcquirePrivateKey仍然给我同样的错误。我相信我在这里只遗漏了一点,因为signtool能够访问私钥

编辑2
屏幕上显示了密钥交换,但我选择了签名

编辑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;
}
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;
}

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

certutil -repairstore -csp "nCipher Enhanced Cryptographic Provider" My <serial number of certificate>
它将打印本地\u Machine\My store中的所有证书。序列号将介于两组之间,如
===============================================================================
。它还将解析有关证书的信息,如序列号、主题等,并运行加密/解密测试以验证证书的可用性

修复绑定后,可以使用此(第二个)命令验证绑定是否正常。不要被第一个命令的输出所愚弄,我从来并没有见过它除了成功之外还能输出任何东西


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

如我在文章中所述,我可以使用

我稍微更改了LinkPrivateKeyfunction,现在它可以工作了

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;
}
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一起集成以获取容器名称。

您已经描述了所采取的步骤,但您的目标是什么?你认为最终结果如何?我需要能够使用HSM上的私钥对某些内容进行签名/解密。我不想导出密钥,我只想能够使用它。您的密钥是否有标签或ID?您是否在HSM中生成密钥?是否从pfx容器导入密钥?密钥已经存在。我不应该创建新的关键点,只是使用已经在HSM中使用过的关键点。他们有身份证和标签,是的!CSP不会将任何内容映射到证书存储