【问题标题】:Read and validate certificate from executable从可执行文件中读取和验证证书
【发布时间】:2011-11-06 16:10:18
【问题描述】:

我想验证签名的可执行映像的证书(通过验证,我的意思是判断签名是否来自 MS/Adobe/Oracle 等)。 Windows 是否为此任务提供 api?我该怎么做,不知道。任何帮助,将不胜感激。 我正在使用 Windows 和 C++。我想验证本机可执行映像,而不是 .NET 程序集或 Java jar 文件。

更新


好的,我会尽快描述我想要的。

1) 验证 PE 证书。签名是否有效。当签名嵌入到 PE 中并且签名在安全目录中时,它应该可以工作。 (我在 sysinternals 论坛上找到了这个并且工作正常,所以我不再需要这个)。

2) 告诉谁是文件的签名者/发布者。我知道它可以通过 CryptQueryObject 实现(我找到了一个工作示例,虽然它不适用于安全目录),但不知道如何将它与安全目录文件一起使用。

【问题讨论】:

    标签: c++ windows validation certificate executable


    【解决方案1】:

    有许多 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 文件类型的基本信息。在您需要的大多数情况下,pvContext 将是 PCCERT_CONTEXT,但如果您使用 .ctl 或 .crl 文件作为输入,它也可以是 PCCRL_CONTEXTPCCTL_CONTEXT。您将收到hStore,其中包含来自文件szFileName 的所有证书。因此,对于pvContexthStore,您可以使用 CryptoAPI 检查包含的文件。如果你喜欢 您可以使用hMsg 的低级按摩API,在某些dwContentType 的情况下将额外设置(至少对于CERT_QUERY_CONTENT_PKCS7_SIGNEDCERT_QUERY_CONTENT_PKCS7_UNSIGNEDCERT_QUERY_CONTENT_PKCS7_SIGNED_EMBED)。

    要验证文件的签名,我建议您使用 CertGetCertificateChainCertVerifyCertificateChainPolicy 来验证证书不仅在一般情况下有效,而且它(或其所有父级)对于验证码(@ 987654352@)。 CertGetCertificateChain 可用于不同的撤销场景。您应该使用 CERT_CHAIN_POLICY_AUTHENTICODECERT_CHAIN_POLICY_AUTHENTICODE_TS 进行两次单独调用,以验证 Authenticode 链策略和 Authenticode 时间戳链策略是否有效。

    已更新:我重读了您当前的问题(已更新部分)。您当前的问题是如何获取文件的签名者/发布者。所以我只回答这个问题。

    如果您使用the code from sysinternal 进行签名验证,您只需搜索该行

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

    该语句仍然设置InfoStruct 的字段,以防该文件是针对某些.cat 文件验证签名的系统windows 文件。 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 没有其他签名者。

    【讨论】:

    • 非常感谢您和 +1,感谢您的宝贵时间。虽然我还有一些问题,但多亏了你,我觉得我比以前更接近目标了:)。当我调用 CryptQueryObject(到 explorer.exe)时,它返回一个错误代码 80092009,这意味着“尝试查找对象时不匹配”。我猜它没有找到 explorer.exe(?) 的目录。再次非常感谢您的努力:)
    • @Davita:如果您尝试检查与 CryptQueryObject 相关的任何文本文件或任何未签名的可执行文件(如 explorer.exe),您将收到 CRYPT_E_NO_MATCH 错误。如果您检查 explorer.exe 的属性,您将看不到“数字签名”选项卡,因此该文件未签名。如果您在实施中遇到其他问题,可以问我。几年前,我花了很多时间在代码签名的 EXE、CAT 等上。所以我可能会很快为您提供帮助。
    • @Davita:不客气!我很高兴能帮助你。我只能重复一遍,如果您在该主题上遇到更多问题,我很乐意再次为您提供帮助。
    • @vitr:不客气!如果不知道您使用的场景,很难回答您。您是否有一些 CAT 文件作为 input 或 EXE 文件(或其他一些签名文件)作为输入?如果您只有 EXE 文件作为输入,则它不包含对 CAT 文件的引用。你想做什么?
    • @vitr:.CAT 文件只不过是文件的哈希列表,应该将其解释为“有效”。在许多情况下,甚至不将文件名(exe 的名称)或文件路径保存为 .CAT 文件的属性。 在安装过程中某些软件产品(例如驱动程序)windows 将相应的 .CAT 文件复制到 C:\Windows\System32\CatRoot\{F750E6C3-38EE-11D1-85E5-00C04FC295EE} 文件夹中,并在公共索引中包含来自 CAT 磁贴的所有哈希值。它允许通过简单调用 CryptCATAdminAcquireContext、CryptCATAdminCalcHashFromFileHandle 函数来获取 CatFileName。
    【解决方案2】:

    WinVerifyTrust 函数对指定对象执行信任验证操作。该函数将查询传递给支持操作标识符(如果存在)的信任提供者。

    对于证书验证,请使用 CertGetCertificateChain 和 CertVerifyCertificateChainPolicy 函数。

    【讨论】:

    • 感谢 John,我尝试了 MSDN 提供的示例,它几乎每次都运行良好,除非我尝试验证诸如 explorer.exe 之类的 Windows 核心文件。它说 explorer.exe 没有签名,但 PeExplorer 告诉我 explorer.exe 的签名已经过验证。我很困惑我错过了什么......
    • 系统文件的哈希值存储在已签名的目录文件中。在此处查看代码:forum.sysinternals.com/…
    • @Bevan Collins,非常感谢,它工作得很好:) 你能告诉我应该如何检索证书信息,例如谁签署了证书?谢谢
    • 如何从 Authenticode 签名的可执行文件support.microsoft.com/default.aspx?scid=kb;en-us;323809获取信息
    • 非常感谢 Bevan,我已经尝试过该代码,但它不适用于安全目录。我不知道如何将 CryptQueryObject 与目录一起使用,并且在网上找不到任何东西。 :(
    【解决方案3】:

    @戴维塔 我仔细阅读了上述问题并试图解决它。

    我的建议是在CryptQueryObject()的第三个参数中尝试CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED而不是CERT_QUERY_CONTENT_FLAG_ALL

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多