如何获取CNG密钥句柄以获取先前导入到Windows Cert:store(在Delphi中)的公共证书?

时间:2019-01-15 10:15:44

标签: signature cng

我需要使用 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密钥句柄,我也会很高兴。

1 个答案:

答案 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;