在Mono上验证x509证书(OS X信任的根证书)

3
我们的应用程序目前使用openssl (http://www.openssl.org/docs/crypto/X509_verify_cert.html) 在未受管控的代码中验证服务器证书。我们正在将其移植到托管代码中。我已经在托管端传输了X509证书,但如何在C#中验证该证书?
a) 有没有一种简单的方法可以根据当前安装的受信任根证书来验证该证书?
b) 如果没有,手动验证的过程是什么?有没有文档记录?
我已经研究了Mono.Security.X509中的类,这为我提供了处理证书和存储的工具,但我遇到了麻烦。
编辑:我在下面添加了我的最终解决方案。 我欢迎进一步反馈意见。

1
这里有一个不错的解释:https://dev59.com/bGs05IYBdhLWcg3wSP9H 。基本上,使用X509Chain,将所有证书放入其中,并构建链。如果需要,您甚至可以选择禁用某些验证步骤。 - mbarthelemy
谢谢。我将我的最终解决方案添加为答案。 - TheNextman
1个回答

5

根据这里这里的信息,我得出以下结论:

  • 理想情况下,我们应该检查证书吊销情况,但这是很复杂的,似乎不值得这样做。
  • 至少我们可以检查证书是否当前并且链是可信任的。
  • 如果需要,我们还可以验证特定于应用程序的事项,例如证书是否为自签名等。

作为一个简单的示例,我们可以使用Mono X509Chain来构建证书链并将其与用户信任的根证书进行验证:

var x509 = new Mono.Security.X509.X509Certificate(certificateBytes);
var chain = new Mono.Security.X509.X509Chain();
bool certificateStatus = chain.Build(x509);

从查看Mono源代码,我可以看到它检查证书链上的信任以及证书上的日期。但是,证书吊销并未实现。

我们还检查证书上的名称与用户连接到的主机名称是否匹配。.NET框架为我们提供了一种简单的获取该信息的方法:

var x5092 = new System.Security.Cryptography.X509Certificates.X509Certificate2(certificateBytes);
string hostName = x5092.GetNameInfo(System.Security.Cryptography.X509Certificates.X509NameType.DnsName, false);
bool hostNameMatch = string.Compare(hostName, this.Server, true) == 0;

证书还可以具有替代名称,应该进行检查,但是在Mono上使用X509NameType.DnsAlternativeName似乎没有实现(它被硬编码为返回string.Empty)。
就我所见,这是一个好的基本解决方案。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接