如何使用C#验证SSL证书 [英] How to validate a SSL certificate with C#

查看:1013
本文介绍了如何使用C#验证SSL证书的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

也许其中一个可以帮助我回答有关在.NET框架中验证证书的问题。不幸的是,我在Internet上的研究过程中仅发现问题的肤浅答案,但没有确切的解释。

maybe one of you can help me answer my question about validating certificates in the .NET framework. Unfortunately I found only superficial answers to my questions during my research on the Internet, but no exact explanation.

同时,我知道我可以使用以下代码检查软件

Meanwhile I know that I can check in my software with the following code whether a certificate is valid.

ServicePointManager.ServerCertificateValidationCallback += ValidateRemoteCertificate;

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

但我现在想知道Microsoft在这里到底在检查什么?框架执行了哪些检查以使结果SslPolicyErrors.None?

But I would now like to know what Microsoft is checking here exactly? What checks were performed by the framework to make the result SslPolicyErrors.None?

例如,根证书是否也在此处以及其来源得到验证?如果是这样,怎么办?

For example, is the root certificate also validated here and where it comes from? If so, how?

您认为仍然有必要(或有用)在这些检查中添加我自己的检查,而.NET Framework尚未这样做?

In your opinion is it still necessary (or useful) to add additionally my own checks to these checks, which the .NET Framework hasn't made yet?

推荐答案

部分重复 c#验证X509Certificate2:我这样做对吗?,从那里得到的简短答案是免费获得的检查(没有自定义处理程序,或者在处理程序之前已经完成):

This is partially just a repeat of c# Validating an X509Certificate2: am I doing this right?, the short form answer from there is that the checks you get for free (with no custom handler, or that are already done before your handler):


  • 证书链有效(否则设置 SslPolicyErrors.RemoteCertificateChainErrors


    • 证书链接到受信任的根颁发机构

    • 证书未过期(或从将来开始)

    • 该证书表明它打算用作TLS服务器证书

    • 如果在请求中启用了撤消(默认情况下处于禁用状态),则链中的所有证书都不会被撤消

    • The certificate chain is valid (otherwise SslPolicyErrors.RemoteCertificateChainErrors is set)
      • The certificate chains up to a trusted root authority
      • The certificate is not expired (or from the future)
      • The certificate indicates that it is intended to be used as a TLS server certificate
      • If revocation was enabled on the request (it's off by default), no certs in the chain are revoked.

      例如,根证书是否也在此处以及其来源得到验证?

      For example, is the root certificate also validated here and where it comes from?

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

      The certificate verification here uses the same root trust list as Internet Explorer, Chrome, Edge, Outlook, et cetera use, which is centrally managed in Windows. (Firefox uses a different root trust list, which is managed only by Firefox.)


      您认为...

      In your opinion ...

      意见问题在StackOverflow上不合时宜。

      Opinion questions are off-topic on StackOverflow.


      it仍然有必要(或有用)向这些检查中添加我自己的检查,而.NET Framework尚未这样做?

      it still necessary (or useful) to add additionally my own checks to these checks, which the .NET Framework hasn't made yet?

      这要视情况而定。

      如果您要连接自己的服务器,并且对证书链有所了解,则可以添加额外的支票。例如,您可能知道服务器使用让我们加密,并且将来自 https://letsencrypt.org/certificates/ ,则可以固定中间件...您只需要确保当它们移至新的中间件时做出反应即可。

      If you are contacting one of your own servers, and you know something to expect about the certificate chain, you could add an extra check. For example, you could know that your server uses Let's Encrypt, and you embed in your application both "Let’s Encrypt Authority X3" certificates from https://letsencrypt.org/certificates/ then you could pin the intermediate... you just need to be sure to react when they move to a new intermediate.

      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的实现会更好一些。

      If you're not going to perform additional checks (or do custom logging, et cetera) then it's better to not even register the callback, because the implementation is a bit nicer with memory and CPU when there's no callback registered.

      这篇关于如何使用C#验证SSL证书的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆