我正在尝试使用Windows CryptoAPI从证书存储访问证书的公共密钥。它可以在x86项目配置下工作,但是在x64配置下失败,因为它填充的结构为空。我无法更改项目的配置,因为那时我必须更改很多事情。有人知道在x64位配置中执行此操作的方法吗?
这是我在x86上拥有的:
HCERTSTORE CertStore = CertOpenStore( CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_SYSTEM_STORE_CURRENT_USER, L"My" );
PCCERT_CONTEXT CertContext = CertFindCertificateInStore( CertStore, X509_ASN_ENCODING|PKCS_7_ASN_ENCODING, 0, CERT_FIND_SUBJECT_STR_A, CertName, NULL );
CryptDecodeObjectEx((PKCS_7_ASN_ENCODING | X509_ASN_ENCODING),
CNG_RSA_PUBLIC_KEY_BLOB,
CertContext->pCertInfo->SubjectPublicKeyInfo.PublicKey.pbData, // The pbData member is filled correctly
CertContext->pCertInfo->SubjectPublicKeyInfo.PublicKey.cbData, // The cbData member is filled with the correct length of the public key
CRYPT_ENCODE_ALLOC_FLAG,
NULL,
&DecodedPublicKey,
&DecodedPublicLength); // Executes with success, returns the public key, which I am sure is correct, because I tested it.
对于x64,我有完全相同的东西,但是pbData和cbData成员未从CertFindCertificateInStore
中填充:
HCERTSTORE CertStore = CertOpenStore( CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_SYSTEM_STORE_CURRENT_USER, L"My" );
PCCERT_CONTEXT CertContext = CertFindCertificateInStore( CertStore, X509_ASN_ENCODING|PKCS_7_ASN_ENCODING, 0, CERT_FIND_SUBJECT_STR_A, CertName, NULL );
CryptDecodeObjectEx((PKCS_7_ASN_ENCODING | X509_ASN_ENCODING),
CNG_RSA_PUBLIC_KEY_BLOB,
CertContext->pCertInfo->SubjectPublicKeyInfo.PublicKey.pbData, // pbData member is null
CertContext->pCertInfo->SubjectPublicKeyInfo.PublicKey.cbData, // cbData member is 0
CRYPT_ENCODE_ALLOC_FLAG,
NULL,
&DecodedPublicKey,
&DecodedPublicLength);
实际上,CertContext
的每个成员都是空的,但是CertFindCertificateInStore
没有返回null,这确实很奇怪。对我来说似乎是个虫子...
找到了解决方案。这是结构对齐。显然,Wincrypt库的32位版本使用与我的配置相同的对齐方式,但是64位版本使用不同的对齐方式。调整固定结构的对齐方式。