如何根据证书主题验证规范名称(通用名称,cn)?

Edw*_*vey 1 c# validation ssl x509certificate

在 C# 中,我创建了一个到服务器的 SSL 连接,如下所示:

var hostname = "www.example.com";
var client = new TcpClient(hostname, 443);
var sslStream = new SslStream(client.GetStream());
sslStream.AuthenticateAsClient(hostname);
Run Code Online (Sandbox Code Playgroud)

上述完成后没有抛出异常,我知道服务器证书已经过验证并且主机名与主题充分匹配。主题可以通过属性访问,sslStream.RemoteCertificate.Subject该属性是 DN 格式的字符串,类似于

CN=www.example.com, O=Example Inc, L=New York, S=New York, C=US
Run Code Online (Sandbox Code Playgroud)

或者

CN=*.example.com, OU=Certificate Authority Validated
Run Code Online (Sandbox Code Playgroud)

出于深奥的原因,我想针对同一证书主题验证另一个字符串(另一个主机名)。如何正确验证特定主机名是否与证书主题匹配?

Edw*_*vey 5

这是相关标准: RFC2818第3.1节。

特别重要的是:问题询问如何解析主题字符串,正确答案是:一般来说,您不应该这样做。至少从 2000 年编写 RFC2818 起,解析主题字符串就已被弃用,取而代之的是 subjectAltName.dNSName。

checkServerIdentity这是单声道实现:(在以下文件中 搜索) https://github.com/mono/mono/blob/master/mcs/class/Mono.Security/Mono.Security.Protocol.Tls.Handshake.Client/TlsServerCertificate 。CS

我之前发布了此信息作为对问题的编辑,并表示它不算是答案,因为代码不完整 - 代码部分标记为TODO和DEPRECATED。但现在我更仔细地审查了代码和 RFC,发现DEPRECATED注释是 RFC 标准所要求的,而且TODO注释实际上已经完成了 - 只是显然有人忘记删除 TODO 注释。