2016-01-07 124 views
0

我使用「CertOpenStore」API打開證書存儲區,並使用「CertEnumCertificatesInStore」API獲取證書。 API返回的CERT_CONTEXT數據以CERT_NAME_BLOB類型給出頒發者名稱。 如何從證書中獲取CERT_RDN或CERT_NAME_INFO? 我的要求是獲取發行者姓名屬性(O,OU等)。我不想解析CertNameToStr API返回的字符串。從證書對象獲取CERT_RDN信息

+0

的最佳方式恕我直言,是使用ASN.1語法分析器。加載原始證書數據(DER編碼),並按照[RFC5280](https://www.ietf.org/rfc/rfc5280.txt)中定義的X509證書的結構查找主題或頒發者。 – pepo

回答

1

以上評論是正確的,你需要解碼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); 
+0

謝謝。有效。 – user2338040