如何在不导入根证书的情况下验证X509证书?
我的程序包含 2 个我了解并信任的根证书。 我必须验证信任中心的证书和信任中心颁发的“用户”证书,它们都源自这两个根证书。
我使用 X509Chain 类进行验证,但仅当根证书位于 Windows 证书存储中时才有效。
我正在寻找一种在不导入这些根证书的情况下验证证书的方法 - 以某种方式告诉 X509Chain 类我确实信任此根证书,并且它应该只检查链中的证书而不检查其他任何内容。
实际代码:
X509Chain chain = new X509Chain();
chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
chain.ChainPolicy.ExtraStore.Add(root); // i do trust this
chain.ChainPolicy.ExtraStore.Add(trust);
chain.Build(cert);
编辑:这是一个.NET 2.0 Winforms 应用程序。
My program contains 2 root certs I know and trust.
I have to verify certs of trustcenters and "user" certs issued by the trustcenters which all originate from these 2 root certs.
I use X509Chain class to verify but that only works if the root cert is in the windows certificate store.
I'm looking for a way to verify the certs without importing theeses root certs - somehow tell the X509Chain class that I do trust this root certs and it should check just the certs in the chain and nothing else.
Actual code:
X509Chain chain = new X509Chain();
chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
chain.ChainPolicy.ExtraStore.Add(root); // i do trust this
chain.ChainPolicy.ExtraStore.Add(trust);
chain.Build(cert);
Edit: It's a .NET 2.0 Winforms application.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我在 dotnet/corefx 上打开了一个问题,他们回复如下:
所以你应该这样做:
I opened an Issue on dotnet/corefx and they replied as follows:
So you should do it this way:
编辑
多年来,我们发现我在此处发布的原始 X509Chain 解决方案存在一些问题,因为 X509Chain 在某些边缘情况下执行了不正确的行为。因此我不再推荐使用 X509Chain 来解决这个问题。此后,我们的产品已转而使用 Bouncy Castle 来进行所有证书链验证,并且它经受住了我们的所有测试,并且始终按预期工作。
我们新解决方案的基础可以在这里找到:在 BouncyCastle 中构建证书链在 C# 中,
我删除了原始答案,因此没有人使用糟糕的安全解决方案。
EDIT
Over the years we found several issues with the original X509Chain solution I had posted here due to X509Chain performing incorrect behaviors for certain edge cases. Thus I can no longer recommend using X509Chain for this problem. Our product has since moved to using Bouncy Castle to do all of our certificate chain verification and it has held up to all of our testing and always works as expected.
The basis of our new solution can be found here: Build certificate chain in BouncyCastle in C#
I have removed the original answer so no one is using a bad security solution.
获得此信息的方法是编写自定义验证。
如果您处于 WCF 上下文中,则可以通过子类化 System.IdentityModel.Selectors.X509CertificateValidator 并在 web.config 中的 serviceBehavior 对象上指定自定义验证来完成:
但如果您只是在寻找一种方法要接受来自另一台主机的 SSL 证书,您可以修改 web.config 文件中的 system.net 设置:
下面是 X509CertificateValidator 的示例,用于测试客户端证书是否存在于 LocalMachine/Personal 存储中。 (这不是您需要的,但作为示例可能有用。
The way to obtain this would be to write a custom validation.
If you are in a WCF context this is done by subclassing the
System.IdentityModel.Selectors.X509CertificateValidator
and specifying the custom validation on the serviceBehavior object in web.config:But if you are just looking at a way to accept SSL certs from another host you can modify the system.net settings in the web.config file:
Below is an example of a X509CertificateValidator that tests if the clients cert is present in the LocalMachine/Personal store. (Which is not what you need but might be useful as an example.
如果您知道哪些证书可以作为要检查的根证书和中间证书,则可以在
X509Chain
ChainPolicy.ExtraStore 集合中加载根证书和中间证书的公钥。代码>对象。我的任务还包括编写一个 Windows 窗体应用程序来安装证书,前提是该证书是根据我国政府已知的“国家根证书”颁发的。允许颁发证书来验证与国家 Web 服务的连接的 CA 数量也有限,因此我拥有一组有限的证书,这些证书可以位于链中,并且可能在目标计算机上丢失。我在应用程序的子目录“cert”中收集了 CA 的所有公钥和政府根证书:
在 Visual Studio 中,我将目录 cert 添加到解决方案中,并将该目录中的所有文件标记为嵌入式资源。这使我能够在我的 C# 库代码中枚举“受信任”证书的集合,以构建一个链来检查证书,即使未安装颁发者证书也是如此。为此,我为 X509Chain 制作了一个包装类:
在调用函数中,我现在可以成功检查未知证书是否派生自国家根证书:
完成图片:检查根证书(通常已安装,因为它是包含在 Windows 更新中,但理论上也可能丢失),我将友好名称和指纹与发布的值进行比较:
我不确定此检查是否完全安全,但在我的情况下,Windows 窗体应用程序的操作员非常肯定能够访问要安装的有效证书。该软件的目标只是过滤证书列表,以帮助他仅在计算机的机器存储中安装正确的证书(该软件还安装中间证书和根证书的公钥,以确保该证书的运行时行为Web 服务客户端是正确的)。
If you know which certificates can be root and intermediate certificates for the certificate to check, you can load the public keys of the root and intermediate certificates in the
ChainPolicy.ExtraStore
collection of theX509Chain
object.My task was also to write a Windows Forms application to install a certificate, only if it was issued dependent on the known "National Root certificate" of my country's government. There also is a limited number of CA's that are allowed to issue certificates to authenticate connections to the national web services, so I had a limited set of certificates that can be in the chain and might be missing on the target machine. I collected all public keys of the CA's and the government root certificates in a subdirectory "cert" of the application:
In Visual Studio, I added the directory cert to the solution and marked all files in this directory as embedded resource. This allowed me to enumerate the collection of "trusted" certificates in my c# library code, to build a chain to check the certificate even if the issuer certificate is not installed. I made a wrapper class for X509Chain for this purpose:
In the calling function, I could now successfully check if an unknown certificate derives from the national root certificate:
To complete the picture: to check the root certificate (that usually is installed because it is included in Windows Update, but in theory could be missing as well), I compare the friendly name and thumbprint to the published values:
I am not sure if this check is secure at all, but in my case the operator of the Windows Forms application is quite sure to have access to a valid certificate to be installed. The goal of the software is just to filter the certificates list to help him install only the correct certificate in the machine store of the computer (the software also installs the public keys of the intermediate and root certificate, to ensure that the runtime behavior of the web service client is correct).
我刚刚扩展了 @Tristan 的代码,并检查了根证书是否是添加到 ExtraStore 的证书之一。
I just extended the code from @Tristan with a check that the root certificate is one of the certificates added to the ExtraStore.