I have a task to sign and decrypt data, but the private keys are located at a HSM ( Luna SA, / Safenet ). I installed all the client software and connected the Luna SA CSP to the test servers.
Using the PKCS#11 functions provided, I am able to list and export the public keys on the HSM as PCCERT_CONTEXT
(CertCreateCertificateContext
). When I try to acquire the private key (using CryptoAPI function CryptAcquireCertificatePrivateKey
), I receive an error code CRYPT_E_NO_KEY_PROPERTY
.
I am probably missing the link between the certificate data and the CSP/HSM. Has anybody done something similar and can give any hints?
I sucessfully created CER files from all the keys located on the HSM.
When i know use signtool.exe
(the one that ships with Microsoft Plattform SDK) i am able to sign a dll with a key on the HSM (the tool wizard lets me choose key container, key spec, ...). I tried to use the information the tool shows me and set the private key
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;
}
but CryptAcquirePrivateKey still gives me the same error. I believe I am missing only a small bit here, since the signtool is able to access the private key
The screnshot shows KEYEXCHANGE but I chose SIGNATURE
I changed the LinkPrivateKey
function a little bit, now it works
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;
}
As stated in my post, I can link the private key using
I changed the LinkPrivateKeyfunction a little bit, now it works
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;
}
YOu have to replace L"MSS"
with the key container defined on you server.
LunSA provides the tool keymap.exe
that is insatlled along with the LunaCSP to get the container names.