signature - 如何获取先前导入到 Windows Cert: 存储(在 Delphi 中)的公共证书的 CNG 密钥句柄?
问题描述
我需要使用CNG来验证消息签名 (RSA )。唯一的问题是如果我将公共证书存储在 Windows 证书(Cert:\CurrentUser\My)中,如何获取 CNG 密钥句柄(NCRYPT_KEY_HANDLE 或 BCRYPT_KEY_HANDLE )。我正在使用一个
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 () 但这又只适用于private keys。
任何人都知道如何使用 CNG 获取公钥句柄?我在一个文件(cer/pem)中有公钥,我将它导入到 WindowsCert:
商店,但如果你知道如何将它直接从文件加载到 CNG 密钥句柄,我也会很高兴。
解决方案
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;
推荐阅读
- angular - 将两个 ngValue 和两个 ngModel 放在一起很热?
- reactjs - 你可以在同一个网站上使用 React 平滑滚动和 React Router Links 吗?
- flutter - RangeSlider 偶尔显示空白标签
- c++ - 如何创建一个 (f)16 重复 n 次的数字?
- javascript - 如何在三行而不是 1 行中显示数据?
- javascript - 累积函数数组中每个函数的返回值
- mysql - 加入 1 到 N 个映射列
- laravel - Laravel 自定义或扩展的 belongsToMany
- c++ - 为什么在键类型中使用引用时 lambda 函数在 std::lower_bound 中不起作用?
- swift - 在 CoreData / SwiftUI 的实体中显示属性中的最高数字