我已经将证书添加到系统存储中,其内容如下:
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驱动程序实现的指南或方法,那将是很棒的!我很难找到这些东西的文档。
所以我找到了下面的解决方案。所有非必要的理解代码都省略了。
迭代商店中的证书并通过其属性查找我的证书,然后使用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);
}
}
}