我已将证书添加到系统存储中,如下所示:
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"));
现在,我正在创建一个密码学服务提供者,需要从此证书中获取公钥以实现CPExportKey()函数。
这可能吗?如果是,该怎么办?
此外,如果有人可以向我介绍CSP驱动程序实施的一种指南或方法,那就太好了!我在寻找这些东西的文档时遇到了麻烦。
答案 0 :(得分: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);
}
}
}