如何从Windows系统certstore中的证书获取公钥

问题描述 投票:2回答:1

我已经将证书添加到系统存储中,其内容如下:

PCCERT_CONTEXT pCertContext;
HCERTSTORE hCertStore;
CRYPT_KEY_PROV_INFO provInfo;

if (pCertContext = CertCreateCertificateContext(MY_ENCODING_TYPE, certDER, certSize)) {
    provInfo.pwszContainerName = idCert;
    provInfo.pwszProvName = provName;
    provInfo.dwProvType = provType;
    provInfo.dwFlags = 0;
    provInfo.cProvParam = 0;
    provInfo.rgProvParam = NULL;
    provInfo.dwKeySpec = AT_SIGNATURE;

    if (!CertSetCertificateContextProperty(pCertContext, CERT_KEY_PROV_INFO_PROP_ID, 0, &provInfo)) Error(TEXT("CertSetCertificateContextProperty"));

    if (!(hCertStore = CertOpenSystemStore(NULL, L"MY"))) Error(TEXT("CertOpenSystemStore"));
    if (!CertAddCertificateContextToStore(hCertStore, pCertContext, CERT_STORE_ADD_REPLACE_EXISTING, NULL)) Error(TEXT("CertAddCertificateContextToStore"));
    CertFreeCertificateContext(pCertContext);
} else Error(TEXT("CertCreateCertificateContext"));

现在我正在创建一个Cryptographyc服务提供程序,需要从此证书中获取公钥以实现CPExportKey()函数。

这可能吗?如果是,我该怎么办?

此外,如果有人能指出我的CSP驱动程序实现的指南或方法,那将是很棒的!我很难找到这些东西的文档。

c++ windows cryptoapi certificate-store
1个回答
2
投票

所以我找到了下面的解决方案。所有非必要的理解代码都省略了。

迭代商店中的证书并通过其属性查找我的证书,然后使用CryptDecodeObjectEx()函数将密钥转换为RSA_CSP_PUBLICKEYBLOB格式。

关键是保持在这个位置pCertContext->pCertInfo->SubjectPublicKeyInfo.PublicKey.pbData和它的大小在pCertContext->pCertInfo->SubjectPublicKeyInfo.PublicKey.cbData

HCERTSTORE hCertStore = NULL;
PCCERT_CONTEXT pCertContext = NULL;
PBYTE pbPKEY = NULL;
DWORD iPKEYSize;

hCertStore = CertOpenSystemStore(NULL, L"MY");

while(pCertContext = CertEnumCertificatesInStore(
    hCertStore,
    pCertContext))
{
    DWORD dwPropId = 0;
    while(dwPropId = CertEnumCertificateContextProperties(
        pCertContext, // The context whose properties are to be listed.
        dwPropId))    // Number of the last property found.  
    {
        // ...
        // here I compare the properties to see if it is the certificate that I want.
        // ...
        CryptDecodeObjectEx((PKCS_7_ASN_ENCODING | X509_ASN_ENCODING), 
            RSA_CSP_PUBLICKEYBLOB, 
            pCertContext->pCertInfo->SubjectPublicKeyInfo.PublicKey.pbData, 
            pCertContext->pCertInfo->SubjectPublicKeyInfo.PublicKey.cbData, 
            CRYPT_ENCODE_ALLOC_FLAG, 
            NULL, 
            &pbPKEY, 
            &iPKEYSize);

            // pbData and pcbDataLen are output parameters of the function
            *pcbDataLen = iPKEYSize;
            memcpy(pbData, pbPKEY, *pcbDataLen);
            LocalFree((HANDLE)pbPKEY);
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.