我需要使用 CNG 来验证消息签名 (RSA )。唯一的问题是,如果我在Windows证书中存储了公共证书,则如何获取CNG密钥句柄( NCRYPT_KEY_HANDLE或BCRYPT_KEY_HANDLE )(证书: \ CurrentUser \ My)。 我正在使用
NCryptOpenStorageProvider({out}hProv, MS_KEY_STORAGE_PROVIDER, 0)
,我尝试使用
公共密钥
NCryptOpenKey(hProv, {out}hKey, PWideChar('my.test.com'), AT_KEYEXCHANGE, 0)
,但是 NCryptOpenKey ()只能打开同时具有私钥的证书。
我也在查看 BCryptImportKeyPair (),但这要求将公钥设置为 BCRYPT_RSAKEY_BLOB 结构,但我不知道该如何实现。
我上次查看的功能是 NCryptImportKey (),但这再次仅适用于私有密钥。
任何人都知道如何使用CNG获得公钥句柄吗?
我在文件(cer / pem)中具有公钥,并将其导入到Windows Cert:
存储中,但是如果您知道如何将其直接从文件加载到CNG密钥句柄,我也会很高兴。>
答案 0 :(得分:1)
NCrypt *函数与存储在密钥存储提供程序中的持久密钥对一起使用。如果您将证书导入证书存储中,并且此证书不包含私钥,则公钥不会保存在KSP中。
您可以使用函数CryptImportPublicKeyInfoEx2来获取BCRYPT_KEY_HANDLE。
C中的示例代码:
HCERTSTORE hStore = nullptr;
PCCERT_CONTEXT pCert = nullptr;
BCRYPT_KEY_HANDLE hKey = nullptr;
/* Open MY certificate store */
hStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_SYSTEM_STORE_CURRENT_USER, L"MY");
if (!hStore) {
goto Exit;
}
/* Find your certificate in store. For example search by subject name */
pCert = CertFindCertificateInStore(hStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_SUBJECT_STR, L"subject name", nullptr);
if (!pCert) {
goto Exit;
}
/* Or if you want to load certificate from file (assuming you read file to cert_data):
pCert = CertCreateCertificateContext(X509_ASN_ENCODING, cert_data, cert_size);
*/
/* Now you can create BCRYPTKEY_HANDLE from your public key */
if (!CryptImportPublicKeyInfoEx2(X509_ASN_ENCODING, &pCert->pCertInfo->SubjectPublicKeyInfo, 0, nullptr, &hKey)) {
goto Exit;
}
/* Now you can verify signature with BCryptVerifySignature(hKey...) */
Exit:
/* Don't forget to free handle after use */
if (hKey) {
BCryptDestroyKey(hKey);
}
if (pCert) {
CertFreeCertificateContext(pCert);
}
if (hStore) {
CertCloseStore(hStore, 0);
}
return 0;