【问题标题】:X509Certificate.CreateFromSignedFile retrieves only the leaf certificateX509Certificate.CreateFromSignedFile 仅检索叶证书
【发布时间】:2016-10-10 07:13:00
【问题描述】:

我有一个使用 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)?

【问题讨论】:

  • 我觉得你需要看看this的回答
  • 感谢您指点我。正如怀疑的那样,似乎只使用 X509Certificate2 对象会给我叶节点。但是,关于该问题的示例仅讨论使用证书文件(即 pfx)导入整个链,而我需要从签名的可执行文件中导入。这可能吗?
  • 好的,我明白了。根据this,您应该能够从您从签名的可执行文件中获得的X509Certificate 创建一个X509Certicate2。有了这个,您就可以构建一个可以验证的证书链。大致:var cert = X509Certificate.CreateFromSignedFile("path\to\signed_file"); var cert2 = new X509Certificate2(cert); 然后var chain = new X509Chain(); var isValid = chain.Build(cert2);
  • 抱歉,之前评论中的链接错误。应该是this

标签: c# .net x509certificate2


【解决方案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.
}

【讨论】:

  • 刚看到这个答案......我需要这个答案的时间跨度已经过去,但出于好奇让我下周试试这个
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-30
  • 1970-01-01
  • 1970-01-01
  • 2013-09-22
相关资源
最近更新 更多