Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何用C验证SSL证书#_C#_.net_Validation_Ssl_Certificate - Fatal编程技术网

C# 如何用C验证SSL证书#

C# 如何用C验证SSL证书#,c#,.net,validation,ssl,certificate,C#,.net,Validation,Ssl,Certificate,也许你们中的一位可以帮助我回答关于在.NET框架中验证证书的问题。不幸的是,我在互联网上的研究中发现,我的问题只有肤浅的答案,但没有确切的解释 同时我知道我可以用下面的代码检查我的软件是否有有效的证书 ServicePointManager.ServerCertificateValidationCallback += ValidateRemoteCertificate; private bool ValidateRemoteCertificate(object sender, X509Cert

也许你们中的一位可以帮助我回答关于在.NET框架中验证证书的问题。不幸的是,我在互联网上的研究中发现,我的问题只有肤浅的答案,但没有确切的解释

同时我知道我可以用下面的代码检查我的软件是否有有效的证书

ServicePointManager.ServerCertificateValidationCallback += ValidateRemoteCertificate;

private bool ValidateRemoteCertificate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors policyErrors)
{
   return policyErrors == SslPolicyErrors.None;
}
但我现在想知道微软到底在检查什么?框架执行了哪些检查以使结果SslPolicyErrors.None

例如,根证书是否也在此处验证?它来自何处?如果是,怎么做


在您看来,是否仍有必要(或有用)在这些检查中添加我自己的检查,而.NET Framework尚未执行这些检查?

这只是部分重复,这里的简短回答是,您可以免费获得这些检查(没有自定义处理程序,或在处理程序之前已经完成):

  • 证书链有效(否则
    SslPolicyErrors.RemoteCertificateChainErrors
    已设置)
    • 证书链接到受信任的根颁发机构
    • 证书未过期(或将来到期)
    • 该证书表示打算用作TLS服务器证书
    • 如果对请求启用了吊销(默认为关闭),则不会吊销链中的任何证书
  • 证书应用于您连接到的主机名(否则
    SslPolicyErrors.RemoteCertificateNameMismatch
    已设置)
例如,根证书是否也在此处验证?它来自何处

此处的证书验证使用与Internet Explorer、Chrome、Edge、Outlook等相同的根信任列表,该列表在Windows中集中管理。(Firefox使用不同的根信任列表,该列表仅由Firefox管理。)

在你看来

意见问题在StackOverflow上是离题的

仍然有必要(或有用)在这些检查中添加我自己的检查,而.NET Framework还没有这样做

那要看情况

如果您正在联系您自己的服务器之一,并且您知道证书链的预期情况,则可以添加额外的检查。例如,您可能知道您的服务器使用Let's Encrypt,并且您在应用程序中嵌入了“Let's Encrypt Authority X3”证书,从那时起,您可以锁定中间。。。你只需要确保当他们移动到一个新的中间体时做出反应

private bool ValidateRemoteCertificate(
    object sender,
    X509Certificate cert,
    X509Chain chain,
    SslPolicyErrors policyErrors)
{
    if (policyErrors != SslPolicyErrors.None)
    {
        return false;
    }

    if (chain.ChainElements.Count != 3)
    {
        return false;
    }

    byte[] foundCert = chain.ChainElements[1].Certificate.RawData;

    return s_letsEncryptX3Direct.SequenceEqual(foundCert) ||
        s_letsEncryptX3Cross.SequenceEqual(foundCert);
}

如果您不打算执行额外的检查(或进行自定义日志记录等),那么最好不要注册回调,因为在没有注册回调的情况下,内存和CPU的实现会更好。

只需检查链状态即可。已存在描述性消息:

    [Test]
    public async Task CheckWhatError()
    {
        var handler = new HttpClientHandler();
        handler.ServerCertificateCustomValidationCallback = ValidateRemoteCertificate;
        var client = new HttpClient(handler);
        try
        {
            using (var msg = new HttpRequestMessage(HttpMethod.Get, "https://expired.badssl.com/"))
            {
                using (var response = await client.SendAsync(msg))
                {
                    // do stuff with the response
                }
            }
        }
        catch (Exception ex)
        {
            throw;
        }
    }

    private bool ValidateRemoteCertificate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors policyErrors)
    {
        if(policyErrors == SslPolicyErrors.RemoteCertificateChainErrors)
        {
            foreach(var cs in chain.ChainStatus)
            {
                Console.WriteLine(cs.StatusInformation);//validation errors here
            }
        }
        return policyErrors == SslPolicyErrors.None;
    }

非常感谢,你帮了我很多忙。