【问题标题】:Validating x509 certificate on Mono (OS X trusted roots)在 Mono 上验证 x509 证书(OS X 受信任的根)
【发布时间】:2013-12-20 00:57:20
【问题描述】:
我们的应用程序目前使用 openssl (http://www.openssl.org/docs/crypto/X509_verify_cert.html) 在非托管代码中验证服务器证书。我们正在将其转移到托管代码中。我将 X509 证书编组到托管端,但是如何在 C# 中验证该证书?
a) 是否有一种简单的方法可以针对当前安装的受信任根验证该证书?
b) 如果不是,验证的手动流程是什么?它是否记录在某处?
我探索了 Mono.Security.X509 中的类,它为我提供了使用证书和存储的工具,但我无法连接这些点。
编辑我在下面添加了我的最终解决方案。我欢迎就该方法提供进一步的反馈。
【问题讨论】:
标签:
ssl
mono
x509certificate
x509
xamarin.mac
【解决方案1】:
根据here和here的信息,我确定如下:
- 理想情况下,我们应该检查证书吊销,但这是不平凡的,似乎不值得努力
- 至少我们可以检查证书是最新的并且链是可信的
- 如果我们愿意,我们还可以验证特定于应用程序的内容,例如证书是否为自签名证书等
举个简单的例子,我们可以使用 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;
证书也可以具有应检查的替代名称,但使用 X509NameType.DnsAlternativeName 似乎并未在 Mono 上实现(硬编码为返回 string.Empty)。
据我所知,这是一个很好的基本解决方案。