2011-09-14 51 views
1

我正試圖從系統商店加載證書。我使用的功能CertFindCertificateInStore從CryptoAPI的:如何使用CryptoAPI加載unicode CN的證書?

std::string certName; 
CERT_RDN_ATTR subjCN; 
subjCN.pszObjId = szOID_COMMON_NAME; 
subjCN.dwValueType = CERT_RDN_PRINTABLE_STRING; 
subjCN.Value.cbData = 2*(certName.size()); 
subjCN.Value.pbData = (BYTE*)certName.c_str(); 
CERT_RDN rdn; 
rdn.cRDNAttr = 1; 
rdn.rgRDNAttr = &subjCN; 

cert = CertFindCertificateInStore (certStore,  
            X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 
            CERT_UNICODE_IS_RDN_ATTRS_FLAG , 
            CERT_FIND_SUBJECT_ATTR, 
            &rdn, 
            NULL); 
  1. 爲什麼我需要爲CERT_RDN_ATTR的dwValueType設置爲CERT_RDN_PRINTABLE_STRING,而不是CERT_RDN_UNICODE_STRING? (我正在使用Unicode。)與CERT_RDN_UNICODE_STRING此代碼不起作用。

  2. 儘管如此,我無法加載包含空白和俄羅斯符號的主題CN的證書。對於簡單的CN名稱(如「foo」),此代碼完美無缺。

我該如何使用unicode名稱加載證書?

回答

1

如果您可以從MSDN文檔的亂碼中瞭解任何內容,那麼您真是太棒了。或許下面寶石可以被解構爲一些照明:

的CERT_UNICODE_IS_RDN_ATTRS_FLAG dwFindFlags值僅與 使用的CERT_FIND_SUBJECT_ATTR和CERT_FIND_ISSUER_ATTR值 dwFindType。如果pvFindPara指向的 CERT_RDN_ATTR結構已使用 Unicode字符串初始化,則必須設置CERT_UNICODE_IS_RDN_ATTRS_FLAG。在進行任何比較之前,與 匹配的字符串將通過使用X509_UNICODE_NAME進行轉換,以提供Unicode 比較。

我猜「字符串匹配」是在您的subjCN.Value.pbData字段。你有沒有使用X509_UNICODE_NAME進行轉換?這似乎是你在CryptEncodeObject函數中做的事情。去那頁讓我的頭受傷了。對不起,你必須成爲接下來要經歷的一件事。

1

我仔細看過文檔。正如我現在明白, 證書名稱團塊包含RDN的編碼陣列屬性 http://msdn.microsoft.com/en-us/library/aa382005(v=vs.85).aspx 每個RDN屬性具有類型 - 如UTF8,UNICODE,T.61和等

當使用CERT_UNICODE_IS_RDN_ATTRS_FLAG爲CertFindCertificateInStore,這個函數轉換suppled字符串 從Unicode到RDN屬性類型的RDN屬性,然後將此值與證書RDN匹配。

所以我用CryptDecodedObject解碼了我的證書,看了看RDN Common Name ant,結果證明這個類型是CERT_RDN_T61_STRING。然後我設置subjCN.dwValueType爲CERT_RDN_T61_STRING代碼已經工作。對於俄羅斯符號,我需要CERT_RDN_UNICODE_STRING。 因此,如果您不知道證書中該屬性的確切代碼,那麼帶有CERT_FIND_SUBJECT_ATTR或CERT_FIND_ISSUER_ATTR的CertFindCertificateInStore對您來說沒有多大用處。

相關問題