X509Certificate.createfrommsignedfile只检索叶子证书

本文关键字:叶子 证书 检索 createfrommsignedfile X509Certificate | 更新日期: 2023-09-27 18:12:14

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

X509Certificate.createfrommsignedfile只检索叶子证书

是,也不是。

在你的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.
}