我想validation已签名的可执行映像的证书(通过validation,我的意思是说,签名是来自MS / Adobe / Oracle等)。 Windows为此任务提供API吗? 我应该怎么做,不知道。 任何帮助,将不胜感激。 我正在使用Windows和C ++。 我想validation本机可执行映像,而不是.NET程序集或Java jar文件。
UPDATE
好吧,我会尽力描述我想要的东西。
1)validationPE证书。 签名是否有效? 当签名被embedded到PE中并且签名在安全目录中时,它应该工作。 ( 我发现这在sysinternals论坛上,工作正常,所以我不需要这个了 )。
2)告诉谁是文件的签署者/发布者。 我知道它可以通过CryptQueryObject(我发现一个工作的例子,虽然它不适用于安全目录),但不知道如何使用它与安全目录文件。
有许多API和方法可以获取和验证可执行文件的签名,以及如何获得您需要的其他附加信息。 问题是你选择哪个级别(像WinVerifyTrust
这样的高级别)
CryptQueryObject函数是用于从CAT或EXE文件中获取密码上下文的最简单的第一个API。 KB323809的代码示例可以帮助您了解如何解码所需信息。 如果使用CAT文件,主要区别在于您应该修改CryptQueryObject的一些参数。 我建议你只使用CERT_QUERY_CONTENT_FLAG_ALL
和CERT_QUERY_FORMAT_FLAG_ALL
而CryptQueryObject
将完成你所需要的所有内容:
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文件作为输入,则PCCERT_CONTEXT
在您需要的大多数情况下将为PCCERT_CONTEXT
,但也可以为PCCRL_CONTEXT
或PCCTL_CONTEXT
。 您将收到来自文件szFileName
所有证书的hStore
。 因此,就pvContext
和hStore
您可以使用CryptoAPI检查包含的文件。 如果您更喜欢低级别的按摩API,则可以使用hMsg
,这些hMsg
将在dwContentType
(至少针对CERT_QUERY_CONTENT_PKCS7_SIGNED
, CERT_QUERY_CONTENT_PKCS7_UNSIGNED
, CERT_QUERY_CONTENT_PKCS7_SIGNED_EMBED
)的情况下进行额外设置。
要验证文件的签名,我建议您使用CertGetCertificateChain和CertVerifyCertificateChainPolicy来验证证书不仅通常证书是有效的,而且它(或其所有父母)对身份验证( szOID_PKIX_KP_CODE_SIGNING
)有效。 CertGetCertificateChain可以用于不同的撤销场景。 您应该使用CERT_CHAIN_POLICY_AUTHENTICODE
和CERT_CHAIN_POLICY_AUTHENTICODE_TS
分别执行两个调用,以验证Authenticode链策略和Authenticode时戳链策略是否有效。
更新 :我重读你目前的问题(更新部分)。 你目前的问题是如何获得文件的签署者/发布者 。 所以我只回答这个问题。
如果您使用sysinternal的代码进行签名验证,您应该只搜索该行
if ( !CryptCATCatalogInfoFromContext(CatalogContext, &InfoStruct, 0) )
如果该文件是签名被验证的系统窗口文件,则语句窗口设置InfoStruct
的字段。 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.cat
的SPC_SP_OPUS_INFO_OBJID
(“1.3.6.1.4.1.311.2.1.12”)属性。 C:\Windows\system32\CatRoot\{F750E6C3-38EE-11D1-85E5-00C04FC295EE}\Package_1_for_KB2515325~31bf3856ad364e35~amd64~~6.1.1.0.cat
(见函数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
签名者。
WinVerifyTrust函数对指定的对象执行信任验证操作。 该函数将查询传递给支持动作标识符的信任提供者(如果存在)。
对于证书验证,请使用CertGetCertificateChain和CertVerifyCertificateChainPolicy函数。
@Davita我彻底地读了上面的问题并试图解决它。
我的建议是在CryptQueryObject()
的第三个参数中尝试CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED
而不是CERT_QUERY_CONTENT_FLAG_ALL
感谢拉格哈夫