从证书对象中获取 CERT_RDN 信息

Get the CERT_RDN information from the certificate object

我正在使用 "CertOpenStore" API 打开证书存储并使用 "CertEnumCertificatesInStore" API 获取证书。 API 返回的 CERT_CONTEXT 数据以 CERT_NAME_BLOB 类型给出发行者名称。 如何从证书中获取 CERT_RDN 或 CERT_NAME_INFO。? 我的要求是获取颁发者名称属性(O、OU 等)。我不想解析 CertNameToStr API 返回的字符串。

以上评论正确,您确实需要解码CERT_NAME_BLOB中的ASN.1编码数据。但是,CryptoAPI 有一个功能可以为您完成此操作 - CryptDecodeObject.

如果你有一个 PCCERT_CONTEXT 句柄 pCertContext,你可以将它解码为 CERT_NAME_INFO 结构,如下所示:

BOOL success = CryptDecodeObject(
    X509_ASN_ENCODING,
    X509_NAME,
    pCertContext->pCertInfo->Issuer.pbData,
    pCertContext->pCertInfo->Issuer.cbData,
    0,
    NULL,
    &dwNameInfoSize);

// (check that CryptDecodeObject succeeded)    

PCERT_NAME_INFO pCertNameInfo = (PCERT_NAME_INFO) malloc(dwNameInfoSize);

// (check that malloc succeeded)

CryptDecodeObject(
    X509_ASN_ENCODING,
    X509_NAME,
    pCertContext->pCertInfo->Issuer.pbData,
    pCertContext->pCertInfo->Issuer.cbData,
    0,
    pCertNameInfo,
    &dwNameInfoSize);

现在您可以像这样遍历 RDN 的不同组件:

for (DWORD i = 0; i < pCertNameInfo->cRDN; i++)
{
    for (DWORD j = 0; j < pCertNameInfo->rgRDN[i].cRDNAttr; j++)
    {
        CERT_RDN_ATTR &rdnAttribute = pCertNameInfo->rgRDN[i].rgRDNAttr[j];

        //
        // Do stuff with the RDN attribute
        //
    }
}

在每次迭代中,rdnAttribute 将根据您的需要设置为发行人名称的不同组成部分。

最后,完成后释放内存:

free(pCertNameInfo);