X509Certificate.CreateFromSignedFile仅检索叶证书

时间:2016-10-10 07:13:00

标签: c# .net x509certificate2

我有一个使用signtool.exe签名的exe文件。如果我使用Windows查看签名(右键单击 - >属性 - >数字签名 - >详细信息 - >查看证书 - >路径),链条看起来像预期的那样:

Verisign
|
---Symantec Class 3 SHA256 Code Signing CA
   |
   ---Me

但是,如果我使用.NET API X509Certificate.CreateFromSignedFile(path)加载证书并使用X509Certificate2UI.DisplayCertificate(cert)查看证书,我只会看到叶证书。当然,由于缺少链条,尝试使用X509Chain构建链条会导致失败。

这是预期的行为,有没有办法使用托管的.NET代码构建整个链(读取,不使用WinVerifyTrust p / invoke)?

1 个答案:

答案 0 :(得分:1)

是的,没有。

在您的UI工作流程中,当您按下"查看证书"您从文件属性对话框切换到CertUI对话框。 CertUI(可能)只查看叶子/终端实体证书,然后构建证书链本身。所以在这一点上,签名文件中还有其他内容。

通过阅读文件中嵌入的所有证书信息,您可以稍微进一步调用。我的本地测试显示它写了EE证书(因为它必须)和中间CA(没有签名行)而不是根证书(因为你通常在传输中省略根证书...另一方已经有它或者不会信任它,所以它浪费了字节)。

var coll = new X509Certificate2Collection();
coll.Import("signedfile.exe");
// My coll had 2 certs at this point.

因此,如果需要帮助解析中间体,您可以将所有这些证书传递给X509Chain.ChainPolicy.ExtraStore,但要确定您仍然需要构建链的根。

using (X509Certificate2 cert = new X509Certificate2("signedfile.exe"))
{
    X509Chain chain = new X509Chain();
    chain.ChainPolicy.VerificationFlags = X509VerificationFlags.IgnoreNotTimeValid;

    bool validChain = chain.Build(cert);

    if (!validChain)
    {
        // Whatever you want to do about that.

        foreach (var status in chain.ChainStatus)
        {
            // In reality you can == this, since X509Chain.ChainStatus builds
            // an object per flag, but since it's [Flags] let's play it safe.
            if ((status.Status & X509ChainStatusFlags.PartialChain) != 0)
            {
                // Incomplete chain.
            }
        }
    }

    X509Certificate2Collection chainCerts = new X509Certificate2Collection();

    foreach (var element in chain.ChainElements)
    {
        chainCerts.Add(element.Certificate);
    }

    // now chainCerts has the whole chain in order.
}