【问题标题】:How to validate canonical name (common name, cn) against certificate subject?如何针对证书主题验证规范名称(通用名称,cn)?
【发布时间】:2014-10-19 22:53:15
【问题描述】:

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

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

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

CN=www.example.com, O=Example Inc, L=New York, S=New York, C=US

CN=*.example.com, OU=Certificate Authority Validated

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

【问题讨论】:

    标签: c# validation ssl x509certificate


    【解决方案1】:

    这里是相关标准:RFC2818 Section 3.1

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

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

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

    【讨论】:

    • 您的另一个 cmets 建议您可能不知道 referencesource.microsoft.com - 我无法确定您希望在哪个类中找到 .NET CLR 实现,但如果它存在,它应该在那里可用。
    • @TomW 谢谢你!不,我不知道... 重要的是要注意许可条款的差异——mono 中的特定文件是 MIT 许可的,而 MS 参考源是 MS-RSL,它的限制更大。此外,显然您只能逐步浏览某些程序集的 .Net 参考源 - 其中不包括 System.Net.Security - 我无法找到 MS 参考代码的相关部分。
    • > 至少在 2000 年编写 RFC2818 时,解析主题字符串已被弃用,支持 subjectAltName.dNSName 我不同意,因为 SAN 不是强制性的,因此您仍然必须解析主题字段。
    • 没有什么不同意的。它写在标准中。引用自 RFC2818:“如果存在类型为 dNSName 的 subjectAltName 扩展,则必须将其用作身份。否则,必须使用证书的 Subject 字段中的(最具体的)Common Name 字段。尽管使用 Common名称是现有做法,已弃用,鼓励证书颁发机构改用 dNSName。”弃用并不意味着你不这样做;这意味着你先做其他事情(如果有的话),只有在别无选择的情况下才使用不推荐使用的方法。
    • RFC2818 是在 2000 年编写的,因此很久以前就可以安全地假设它已被完全采用,并且在实践中,您永远不会遇到缺少 dNSName 的证书,除非您以某种方式导致它自己发生.因此,正如标准所说,首先检查 dNSName,然后再返回解析 Common Name。尽管它在实践中永远不会发生,但为了符合标准,您仍然需要这样做。
    【解决方案2】:

    如果要模拟 SSL 主题名称验证,则必须做一些工作,因为这个过程不是很简单。以下是在证书中实施主题名称验证的指南:

    1. 评估 X509Certificate2 对象的主题备用名称扩展。如果此扩展不存在,则:

    1.1。使用以下正则表达式模式从证书中提取 CN 属性:'CN=([^,]+)' 并使用所需的名称对其进行验证。由于 CN 属性可能包含通配符,因此您应该使用正则表达式对其进行验证。这是一个简单的通配符类的例子。

    class Wildcard : Regex {
        public Wildcard(String pattern) : base(WildcardToRegex(pattern)) { }
        public Wildcard(String pattern, RegexOptions options) : base(WildcardToRegex(pattern), options) { }
        public static String WildcardToRegex(String pattern) {
            return "^" + Escape(pattern).Replace("\\*", ".*") + "$";
        }
    }
    
    1. 如果存在 SAN 扩展,请忽略主题字段验证,并以相同方式对 DNSName 和 IPAddress 备用名称的集合使用地址验证。

    2. 如果第 1 步或第 2 步成功,请检查完整的证书链(直至根证书)以进行名称约束扩展端验证:

      3.1。如果 Name Constraints 定义了 Exclude 部分,则验证另一个名称是否与列表中的任何条目不匹配。否则,此证书不允许使用该名称(不执行步骤 3.2)。

      3.2。如果 Name Constraints 定义了 Include 部分,则验证另一个名称是否与该部分中的任何条目匹配。如果其他名称不属于“包含”部分中的任何条目,则此证书不允许使用此名称。

    不幸的是,.NET 没有代表 SAN 扩展的本机类,因此您必须编写自己的解码器或使用我自己的 .NET 扩展库 (PKI.Core.dll),来自 PowerShell PKI project

    以下类表示 SAN 扩展:http://pkix2.sysadmins.lv/library/html/T_System_Security_Cryptography_X509Certificates_X509SubjectAlternativeNamesExtension.htm

    【讨论】:

    • 谢谢,事实上这个答案可能意外地正确,但是可能有一个 30 页长的标准写在某处,正式定义了主题的确切格式。在幕后,我确信他们已经阅读了该标准并进行了相应的编码。我无权访问幕后的源代码(也许会找到它的单声道源代码,但在短短几分钟内还没有找到)。其他项目——openssl、bouncycastle 等,肯定有可读的源代码……我不想在这里发明一个新的解决方案。我想确保我做对了。
    • 这不是很常见的任务。我不知道有任何 API 或工具可以检查抽象 URL(主机名)是否与连接上下文之外的主题字符串匹配。因此,您将不得不使用活动连接(就像您已经做的那样)或实现您自己的 URL->主题验证器。
    • 我知道。如果 SslStream.AuthenticateAsClient 使用的方法被公开以供一般使用会很酷 - 但它没有公开 - 所以我希望我必须重新创建它。正如这个答案中所写的那样很容易做到,只需编写一些正则表达式代码,以看起来有意义的方式解析字符串。但我想更加确定它做得对。这意味着要么找到一个示例来遵循(MS 源代码、单声道源等),要么找到写在某处的标准,以便可以遵循。
    • 例如,我只提到了特定主机名和通配符的 SSL 证书。还存在用于多个主机名的 SSL 证书。这些将如何格式化?我不知道。但我知道上面的正则表达式不能处理它们......还有其他可能性吗?我不知道...
    • 即主题字段可能为空或包含某些条目。 Web 浏览器仅查找 SAN 扩展以查找适用的名称,名称匹配的执行方式与主题字段相同(支持通配符)。但是,请注意,“*”字符允许同一域级别的多个名称。也就是说,DNSName=*.domain.com 对 www.server2.domain.com 主机名无效。如果可以执行证书链,则可以跳过名称约束扩展处理。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-09
    • 2011-08-21
    • 2014-01-25
    • 2014-06-24
    • 1970-01-01
    相关资源
    最近更新 更多