C# X509Certificate2.Verify 无撤销测试
Posted
技术标签:
【中文标题】C# X509Certificate2.Verify 无撤销测试【英文标题】:C# X509Certificate2.Verify without revocation test 【发布时间】:2019-04-21 12:43:17 【问题描述】:我尝试使用 X509Certificate2.Verify() 函数来检查证书链是否有效。 验证函数返回 false,ChainElementStatus 返回“RevocationStatusUnknown”。
有没有办法在不检查 RevocationStatus 的情况下使用验证功能?没有互联网连接就无法检查 RevocationStatus?是否有其他功能可以在没有 RevocationStatus 的情况下检查链和证书?
一个肮脏的解决方案是检查 RevocationStatus 是否是 element.ChainElementStatus 中的唯一元素。
我已经使用 X509RevocationMode.Offline 和 IgnoreCertificateAuthorityRevocationUnknown。
代码来自:X509Certificate2.Verify() method always return false for the valid certificate
X509Chain ch = new X509Chain();
ch.Build(certificate);
ch.ChainPolicy.RevocationMode = X509RevocationMode.Offline;
ch.ChainPolicy.VerificationFlags = X509VerificationFlags.IgnoreCertificateAuthorityRevocationUnknown;
Console.WriteLine("Chain Information");
Console.WriteLine("Chain revocation flag: 0", ch.ChainPolicy.RevocationFlag);
Console.WriteLine("Chain revocation mode: 0", ch.ChainPolicy.RevocationMode);
Console.WriteLine("Chain verification flag: 0", ch.ChainPolicy.VerificationFlags);
Console.WriteLine("Chain verification time: 0", ch.ChainPolicy.VerificationTime);
Console.WriteLine("Chain status length: 0", ch.ChainStatus.Length);
Console.WriteLine("Chain application policy count: 0", ch.ChainPolicy.ApplicationPolicy.Count);
Console.WriteLine("Chain certificate policy count: 0 1", ch.ChainPolicy.CertificatePolicy.Count, Environment.NewLine);
//Output chain element information.
Console.WriteLine("Chain Element Information");
Console.WriteLine("Number of chain elements: 0", ch.ChainElements.Count);
Console.WriteLine("Chain elements synchronized? 0 1", ch.ChainElements.IsSynchronized, Environment.NewLine);
foreach (X509ChainElement element in ch.ChainElements)
Console.WriteLine("Element issuer name: 0", element.Certificate.Issuer);
Console.WriteLine("Element certificate valid until: 0", element.Certificate.NotAfter);
Console.WriteLine("Element certificate is valid: 0", element.Certificate.Verify());
Console.WriteLine("Element error status length: 0", element.ChainElementStatus.Length);
Console.WriteLine("Element information: 0", element.Information);
Console.WriteLine("Number of element extensions: 01", element.Certificate.Extensions.Count, Environment.NewLine);
if (ch.ChainStatus.Length >= 1)
for (int index = 0; index < element.ChainElementStatus.Length; index++)
Console.WriteLine(element.ChainElementStatus[index].Status);
Console.WriteLine(element.ChainElementStatus[index].StatusInformation);
结果:
链信息 链撤销标志:ExcludeRoot 链撤销模式:离线 链验证标志:IgnoreCertificateAuthorityRevocationUnknown 链上验证时间:19.11.2018 07:53:31 链状态长度:1 链应用策略计数:0 链证书策略计数:0
链元素信息 链元数:2 链元素同步?假的
元素发行者名称:CN=TestRootCA 元素证书有效期至:01.01.2019 00:00:00 元素证书是否有效:False 元素错误状态长度:1 元素信息: 元素扩展数:5
RevocationStatusUnknown Die Sperrfunktion konnte keine Sperrprüfung für das Zertifikat durchführen。
元素发行者名称:CN=TestRootCA 元素证书有效期至:01.01.2019 00:00:00 元素证书有效:真 元素错误状态长度:0 元素信息: 元素扩展数:2
【问题讨论】:
【参考方案1】:我已经使用 X509RevocationMode.Offline 和 IgnoreCertificateAuthorityRevocationUnknown。
IgnoreCertificateAuthorityRevocationUnknown 的意思是“不要因为这个原因让chain.Build
返回false
。”
当然,你是在调用chain.Build之后设置的,并没有检查chain.Build的返回值。
如果您想忽略撤销,请将ChainPolicy.RevocationMode
设置为X509RevocationMode.NoCheck
。如果您希望检查它是否已缓存,如果没有缓存则忽略它,则将模式设置为 Offline 并声明所有 RevocationUnknown 标志即可。
如果证书/链通过了所有未被通过 VerificationFlags 值标记为忽略的有效性检查,则来自 chain.Build 的布尔返回为真。
所以最短的“告诉我这个证书是否没有过期,有一个可解析的链,链的终点是我信任的东西,我不关心撤销”是
using (X509Chain ch = new X509Chain())
ch.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
return ch.Build(certificate);
机会主义撤销将是
using (X509Chain ch = new X509Chain())
ch.ChainPolicy.RevocationMode = X509RevocationMode.Offline;
ch.ChainPolicy.VerificationFlags =
X509VerificationFlags.IgnoreEndRevocationUnknown |
X509VerificationFlags.IgnoreCertificateAuthorityRevocationUnknown |
X509VerificationFlags.IgnoreRootRevocationUnknown;
return ch.Build(certificate);
【讨论】:
为我工作。谢谢。 @SchmidtA 如果此答案解决了您的问题,通常的行为是点击复选标记将其标记为已接受的答案:)以上是关于C# X509Certificate2.Verify 无撤销测试的主要内容,如果未能解决你的问题,请参考以下文章
C#模拟Http请求时出现 基础连接已经关闭 未能为 SSLTLS 安全通道建立信任关系