ssl 如何完整验证X509证书?

rn0zuynd  于 2023-10-19  发布在  其他
关注(0)|答案(1)|浏览(176)

我需要验证一个证书(X509Certificate2),就像在它用于通信之前验证它一样。
在这种情况下,X509Certificate2.Verify()将返回true,而证书未颁发给安装它的服务器。
是否有任何完成的代码块来完成X509证书的完整验证?
问候
编辑:这是我尝试过的代码:

var certificate = GetServerCertificate(CertificateStore,CertificateLocation,Thumbprint);

            if(certificate != null)
            {
                if(certificate.Verify())
                    _logger.Log(NLog.LogLevel.Info, $"Yes");
                else
                    _logger.Log(NLog.LogLevel.Info, $"No");
            }
jm2pwxwz

jm2pwxwz1#

在这种情况下,X509Certificate2.Verify()将返回true,而证书未颁发给安装它的服务器。
Verify方法不检查任何关于主机名的内容。验证了

  • 证书未过期。
  • 证书最终链接到受信任的根颁发机构。
  • 链中的所有证书都有适当的嵌套过期。
  • 目标证书(除非是自颁发的)具有吊销端点,并且不会被吊销。
  • 任何中间证书都有吊销端点,并且不会被吊销。

它正好等于

using (X509Chain chain = new X509Chain())
{
    // Use the default vales of chain.ChainPolicy including:
    //  RevocationMode = X509RevocationMode.Online
    //  RevocationFlag = X509RevocationFlag.ExcludeRoot
    //  VerificationFlags = X509VerificationFlags.NoFlag
    //  VerificationTime = DateTime.Now
    //  UrlRetrievalTimeout = new TimeSpan(0, 0, 0)

    bool verified = chain.Build(cert);

    for (int i = 0; i < chain.ChainElements.Count; i++)
    {
        chain.ChainElements[i].Certificate.Dispose();
    }

    return verified;
}

是否有任何完成的代码块来完成X509证书的完整验证?
如果“完全验证”只是指Verify所做的所有事情,那么是的。如果您还关心它是否可以用作TLS客户端证书(或TLS服务器证书),那么您可以使用较长的形式(直接使用X509 Chain),并在调用chain之前添加应用程序策略要求。

// See if it's valid as a TLS server
chain.ChainPolicy.ApplicationPolicy.Add(new Oid("1.3.6.1.5.5.7.3.1"));
// Alternatively, if it's valid as a TLS client
chain.ChainPolicy.ApplicationPolicy.Add(new Oid("1.3.6.1.5.5.7.3.2"));

hostname比较难。客户端证书没有可验证的名称,这取决于服务器如何使用它。服务器证书具有与SAN/Subject-CN匹配的主机名,但是除了使用TLS(SslStream)连接之外,没有任何内置的检查。

更新(2023-09-08):从.NET 7开始,可以通过MatchesHostname方法在X509 Certificate 2示例上验证主机名。

相关问题