X509Certificate.CreateFromSignedFile 仅检索叶证书
X509Certificate.CreateFromSignedFile retrieves only the leaf certificate
我有一个使用 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)?
是,也不是。
在您的 UI 工作流程中,当您按下 "View Certificate" 时,您会从文件属性对话框切换到证书UI 对话框。 CertUI(可能)只查看 leaf/end-entity 证书,然后自行构建证书链。所以在这一点上,签名文件中的其他内容有点没有实际意义。
通过阅读文件中嵌入的所有证书信息,您可以在一次调用中获得更多信息。我的本地测试表明它写了 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.
}
我有一个使用 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)?
是,也不是。
在您的 UI 工作流程中,当您按下 "View Certificate" 时,您会从文件属性对话框切换到证书UI 对话框。 CertUI(可能)只查看 leaf/end-entity 证书,然后自行构建证书链。所以在这一点上,签名文件中的其他内容有点没有实际意义。
通过阅读文件中嵌入的所有证书信息,您可以在一次调用中获得更多信息。我的本地测试表明它写了 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.
}