我可以使用 MMC 使用 Base 64 编码的 X509 .CER 选项提取相同的公钥。
我的目标是使用 win32 api 以编程方式获取此信息。
到目前为止,我已尝试过以下操作,但存储在 base64Cert 中的数据与公钥不匹配。
关于我可以尝试获取正确数据的任何想法吗?
HCERTSTORE hCertStore;
PCCERT_CONTEXT pCertContext = NULL;
if (!(hCertStore = CertOpenStore(
CERT_STORE_PROV_SYSTEM,
MY_ENCODING_TYPE,
NULL,
CERT_SYSTEM_STORE_LOCAL_MACHINE,
L"MY")))
{
std::cout<<"The MY system store did not open."<< std::endl;
}
while (pCertContext = CertEnumCertificatesInStore(
hCertStore,
pCertContext))
{
LPTSTR pszString;
LPTSTR pszName;
DWORD cbSize;
CERT_BLOB blobEncodedName;
PBYTE pbPKEY = NULL;
DWORD iPKEYSize;
bool ret = CryptDecodeObjectEx(X509_ASN_ENCODING,
RSA_CSP_PUBLICKEYBLOB,
pCertContext->pCertInfo->SubjectPublicKeyInfo.PublicKey.pbData,
pCertContext->pCertInfo->SubjectPublicKeyInfo.PublicKey.cbData,
CRYPT_ENCODE_ALLOC_FLAG,
NULL,
&pbPKEY,
&iPKEYSize);
CERT_CONTEXT certcontext;
certcontext.pbCertEncoded = pbPKEY;
certcontext.cbCertEncoded = iPKEYSize;
DWORD dwData;
if (!CryptBinaryToStringA(certcontext.pbCertEncoded, certcontext.cbCertEncoded, CRYPT_STRING_BASE64HEADER, nullptr, &dwData))
{
std::cout << "error \n";
}
std::string base64Cert(dwData, '\0');
CryptBinaryToStringA(certcontext.pbCertEncoded, certcontext.cbCertEncoded, CRYPT_STRING_BASE64HEADER, &base64Cert[0], &dwData);
std::cout << base64Cert << "\n";
}
您不需要解码
pCertContext->pCertInfo->SubjectPublicKeyInfo.PublicKey
但需要编码 pCertContext->pCertInfo->SubjectPublicKeyInfo
template <typename T>
T HR(HRESULT& hr, T t)
{
hr = t ? NOERROR : GetLastError();
return t;
}
HRESULT mm(PCSTR psz)
{
ULONG cch = (ULONG)strlen(psz);
if (cch > 32*2)
{
return ERROR_INVALID_PARAMETER;
}
CRYPT_HASH_BLOB hash {};
HRESULT hr;
while(HR(hr, CryptStringToBinaryA(psz, cch, CRYPT_STRING_HEX, hash.pbData, &hash.cbData, 0, 0)))
{
if (hash.pbData)
{
if (HCERTSTORE hCertStore = HR(hr, CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0,
CERT_STORE_OPEN_EXISTING_FLAG|CERT_STORE_READONLY_FLAG|CERT_SYSTEM_STORE_CURRENT_USER, L"My")))
{
PCCERT_CONTEXT pCertContext = HR(hr, CertFindCertificateInStore(hCertStore, 0, 0, CERT_FIND_HASH, &hash, 0));
CertCloseStore(hCertStore, 0);
if (pCertContext)
{
PBYTE pb = 0;
ULONG cb = 0;
if (HR(hr, CryptEncodeObjectEx(X509_ASN_ENCODING, X509_PUBLIC_KEY_INFO,
&pCertContext->pCertInfo->SubjectPublicKeyInfo,
CRYPT_ENCODE_ALLOC_FLAG|CRYPT_ENCODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG, 0, &pb, &cb)))
{
cch = 0, psz = 0;
PSTR buf = 0;
int len = 0;
static const char _____[] = "-----";
static const char PUBLIC_KEY[] = " PUBLIC KEY";
static const char BEGIN[] = "BEGIN";
static const char END[] = "END";
static const char fmt[] = "%s%s%s%s\r\n";
#define LEN_OF(s) (_countof(s) - 1)
enum {
cch_prefix = LEN_OF(_____)*2 + LEN_OF(PUBLIC_KEY) + LEN_OF(BEGIN) + 2,
cch_suffix = LEN_OF(_____)*2 + LEN_OF(PUBLIC_KEY) + LEN_OF(END) + 2
};
while (HR(hr, CryptBinaryToStringA(pb, cb, CRYPT_STRING_BASE64, const_cast<PSTR>(psz), &cch)))
{
if (psz)
{
cch += len;
if (0 < (len = sprintf_s(buf + cch, cch_suffix + 1, fmt, _____, END, PUBLIC_KEY, _____)))
{
cch += len;
do
{
len = min(0x80, cch);
DbgPrint("%.*s", len, buf);
} while (buf += len, cch -= len);
}
else
{
hr = ERROR_INTERNAL_ERROR;
}
break;
}
buf = (PSTR)alloca(cch + cch_suffix + cch_prefix);
len = sprintf_s(buf, cch_prefix + 1, fmt, _____, BEGIN, PUBLIC_KEY, _____);
if (0 >= len)
{
hr = ERROR_INTERNAL_ERROR;
break;
}
psz = buf + len;
}
LocalFree(pb);
}
CertFreeCertificateContext(pCertContext);
}
}
break;
}
hash.pbData = (PBYTE)alloca(hash.cbData);
}
return hr;
}