如何从 windows 系统 certstore 中的证书中获取 public 密钥
How to get the public key from a certificate in windows system certstore
我已将证书添加到系统商店,如下所示:
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 Service Provider,需要从此证书中获取 public 密钥以实现 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);
}
}
}
我已将证书添加到系统商店,如下所示:
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 Service Provider,需要从此证书中获取 public 密钥以实现 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);
}
}
}