2011-08-30 104 views
12

我想驗證已簽名的可執行映像的證書(通過驗證,我的意思是告訴簽名是否來自MS/Adob​​e/Oracle等)。 Windows爲此任務提供API嗎?我應該怎麼做,不知道。任何幫助,將不勝感激。 我使用Windows和C++。我想驗證本機可執行映像,而不是.NET程序集或Java jar文件。閱讀並驗證可執行文件的證書

UPDATE


好吧,我會盡力來形容我想不久。

1)驗證PE證書。簽名是否有效?它應該在簽名嵌入到PE中並且簽名在安全目錄中時工作。 (我在sysinternals論壇上發現了這個問題,並且工作正常,所以我不需要這個)。

2)告訴誰是文件的簽署者/發佈者。我知道它可以通過CryptQueryObject來實現(我發現了一個工作示例,雖然它不適用於安全目錄),但不知道如何將它與安全目錄文件一起使用。

回答

20

有很多API和方法可以獲取和驗證可執行文件的簽名以及如何獲得您需要的其他附加信息。問題在於你選擇哪個級別(高級別,如WinVerifyTrust

可用於從CAT或EXE文件獲取加密上下文的最簡單的第一個API是CryptQueryObject函數。 KB323809的代碼示例可以讓您瞭解如何解碼所需信息的主要思想。如果您使用CAT文件,主要區別在於您應該修改CryptQueryObject的一些參數。我建議你只使用CERT_QUERY_CONTENT_FLAG_ALLCERT_QUERY_FORMAT_FLAG_ALLCryptQueryObject會做你需要內部的所有東西:

BOOL bIsSuccess; 
DWORD dwEncoding, dwContentType, dwFormatType; 
HCERTSTORE hStore = NULL; 
HCRYPTMSG hMsg = NULL; 
PVOID pvContext = NULL; 

// fill szFileName 
... 

// Get message handle and store handle from the signed file. 
bIsSuccess = CryptQueryObject (CERT_QUERY_OBJECT_FILE, 
           szFileName, 
           CERT_QUERY_CONTENT_FLAG_ALL, 
           CERT_QUERY_FORMAT_FLAG_ALL, 
           0, 
           &dwEncoding, 
           &dwContentType, 
           &dwFormatType, 
           &hStore, 
           &hMsg, 
           &pvContext); 

CryptQueryObject設置的值dwContentType將讓你有關文件szFileName類型的基本信息。如果您使用.ctl或.crl文件作爲輸入,則pvContext對於您需要的大多數情況將爲PCCERT_CONTEXT,但它也可以是PCCRL_CONTEXTPCCTL_CONTEXT。您將收到文件szFileName中填寫的所有證書的hStore。因此,就pvContexthStore而言,您可以使用CryptoAPI檢查包含的文件。如果您更喜歡 低級別按摩API,則可以使用hMsg,在dwContentType(至少對於CERT_QUERY_CONTENT_PKCS7_SIGNED,CERT_QUERY_CONTENT_PKCS7_UNSIGNED,,CERT_QUERY_CONTENT_PKCS7_SIGNED_EMBED)的情況下將另外設置該值。

來驗證文件的,我會建議你使用CertGetCertificateChainCertVerifyCertificateChainPolicy驗證不僅證書一般有效簽名,但它(或者其所有的父母)是有效的驗證碼(szOID_PKIX_KP_CODE_SIGNING)。 CertGetCertificateChain可用於不同的撤銷方案。您應該分別撥打CERT_CHAIN_POLICY_AUTHENTICODECERT_CHAIN_POLICY_AUTHENTICODE_TS兩次,以驗證Authenticode鏈策略和Authenticode時間戳鏈策略是否有效。

已更新:我重讀了您當前的問題(更新的部分)。您當前的問題是如何獲取文件的簽署者/發佈者。所以我只回答這個問題。

如果你的簽名驗證使用the code from sysinternal你應該只是搜索線

if (!CryptCATCatalogInfoFromContext(CatalogContext, &InfoStruct, 0)) 

聲明門檻設置InfoStruct領域的情況下該文件是簽名相對於驗證系統windows文件一些.cat文件。字段InfoStruct.wszCatalogFile將爲您提供.cat文件的名稱。

例如,在我的Windows 7上,如果我嘗試驗證C:\Windows\explorer.exe文件的數字簽名,可以找到它的哈希值的.cat文件爲C:\Windows\system32\CatRoot\{F750E6C3-38EE-11D1-85E5-00C04FC295EE}\Package_1_for_KB2515325~31bf3856ad364e35~amd64~~6.1.1.0.cat

如果你想從KB323809以上的CryptQueryObject參數來描述使用的代碼,你將解碼C:\Windows\system32\CatRoot\{F750E6C3-38EE-11D1-85E5-00C04FC295EE}\Package_1_for_KB2515325~31bf3856ad364e35~amd64~~6.1.1.0.catSPC_SP_OPUS_INFO_OBJID(「1.3.6.1.4.1.311.2.1.12」)屬性(參見功能GetProgAndPublisherInfo),你就會知道

pwszProgramName: "Windows Express Security Catalogs" 
pPublisherInfo: NULL 
pMoreInfo->dwLinkChoice: SPC_URL_LINK_CHOICE 
pMoreInfo->pwszUrl "http://www.microsoft.com" 

因此沒有特殊的發佈者信息被包括在文件中。如果您檢查目錄的簽名者,你會發現:

The signer of the .cat file: "Microsoft Windows" 
The signer signed it with the certificate: 
    Serial Number: 0x6115230F00000000000A 
    Issuer Name: Microsoft Windows Verification PCA 
    Full Issuer Name: 
     CN = Microsoft Windows Verification PCA 
     O = Microsoft Corporation 
     L = Redmond 
     S = Washington 
     C = US 
    Subject Name: Microsoft Windows 
    Full Subject Name: 
     CN = Microsoft Windows 
     OU = MOPR 
     O = Microsoft Corporation 
     L = Redmond 
     S = Washington 
     C = US 
The Date of TimeStamp : 28.02.2011 21:16:36 
TimeStamp Certificate: 
    Serial Number: 0x6103DCF600000000000C 
    Issuer Name: Microsoft Time-Stamp PCA 
    Subject Name: Microsoft Time-Stamp Service 

所以,你應該使用.cat文件只是簽名,因爲也有explorer.exe沒有其他簽名者。

+0

非常感謝你和+1,我感謝你的時間。雖然我仍然有一些問題,感謝你,我覺得我比以前更接近目標:)。當我調用CryptQueryObject(對explorer.exe)時,它返回錯誤代碼80092009,這意味着「嘗試查找對象時不匹配」。我想它沒有找到explorer.exe(?)的目錄。非常感謝你的努力:) – Davita

+0

@Davita:如果你想嘗試檢查任何文本文件或任何未簽名的可執行文件(如資源管理器。exe)相對於'CryptQueryObject'你會收到[CRYPT_E_NO_MATCH](http://msdn.microsoft.com/en-us/library/aa909166.aspx)錯誤。如果您檢查explorer.exe的屬性,您將不會看到「數字簽名」選項卡,因此該文件未被簽名。如果你在執行中會遇到其他問題,你可以問我。幾年前我花了很多時間在代碼簽名EXE,CAT等等。所以我可能會很快幫到你。 – Oleg

+0

非常感謝奧列格,我非常感謝你的努力。還是有些混亂。 http://forum.sysinternals.com/howto-verify-the-digital-signature-of-a-file_topic19247.html < - 當我用這段代碼檢查explorer.exe時,WinVerifyTrust告訴簽名是有效的。我是否缺少某些東西或PE簽名和目錄文件有不同的用途?對不起,這個愚蠢的問題,我真的需要得到這個工作:(再次感謝 – Davita

3

WinVerifyTrust函數對指定的對象執行信任驗證操作。該函數將查詢傳遞給支持動作標識符的信任提供者(如果存在)。

對於證書驗證,請使用CertGetCertificateChain和CertVerifyCertificateChainPolicy函數。

+0

感謝約翰的第三個參數,我試圖通過MSDN提供的例子,除了當我嘗試驗證Windows核心文件,比如它的偉大工程,幾乎每次, explorer.exe的。它說Explorer.exe沒有簽名,但是PeExplorer告訴我explorer.exe的簽名已經過驗證。我很困惑我失蹤了什麼...... – Davita

+1

系統文件的哈希存儲在已簽名的目錄文件中。看到代碼在這裏:http://forum.sysinternals.com/howto-verify-the-digital-signature-of-a-file_topic19247.html –

+0

@貝文柯林斯,非常感謝你,它工作正常:)請你告訴我應該如何檢索證書信息,例如誰簽署了證書?謝謝 – Davita

1

@Davita 我徹底地閱讀了上述問題並試圖解決它。

我的建議是嘗試CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED而不是CERT_QUERY_CONTENT_FLAG_ALLCryptQueryObject()