【问题标题】:.Net Programming: What to validate on an SSL self-signed certificate.Net 编程:在 SSL 自签名证书上验证什么
【发布时间】:2012-06-29 03:38:57
【问题描述】:

我无法让用户为他们的服务器创建真正的证书,但我想做一些安全检查。所以以下内容太轻了,因为在我阅读时,没有检查证书。

ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

您有什么建议让客户检查 x509 证书?鉴于我使用的是 .NET 语言 (c#/f#)。

【问题讨论】:

    标签: .net ssl-certificate


    【解决方案1】:

    如果您使用的是自签名证书,那么您应该预料到的唯一错误是根(证书颁发者)上的链错误。我会建议这样的东西,专门针对该链错误并让所有其他错误都失败。

    ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(
        ValidateRemoteCertificate
    );
    
    private static bool ValidateRemoteCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors policyErrors )
    {
        string trustedIssuer = "CN=www.domain.com";
        string trustedDomain = "CN=www.domain.com";
        bool policyErr = false;
    
        switch (policyErrors)
        {
            case SslPolicyErrors.None:
                policyErr |= false;
                break;
            case SslPolicyErrors.RemoteCertificateChainErrors:
                bool chainErr = false;
                foreach (X509ChainStatus status in chain.ChainStatus)
                {
                    switch (status.Status)
                    {
                        case X509ChainStatusFlags.NoError:
                            chainErr |= false;
                            break;
                        case X509ChainStatusFlags.UntrustedRoot:
                            if (certificate.Subject != trustedDomain || certificate.Issuer != trustedIssuer)
                                chainErr |= true;
                            else
                                chainErr |= false;
                            break;
                        default:
                            chainErr |= true;
                            break;
                    }                    
                }
                policyErr |= chainErr;
                break;
            default:
                policyErr |= true;
                break;
        }
    
        return !policyErr;
    }
    

    【讨论】:

      【解决方案2】:

      如果您无法让客户端创建真正的证书,您至少应该尝试让他们使用您的服务器创建证书。然后您可以检查证书是否有效或至少来自您的 CA,因为您会知道您的 CA 是否已被盗用。如果您信任任何和所有 CA,那么真的没有什么值得检查的。

      【讨论】:

      • +1 完全同意。除非您可以信任颁发 CA,否则证书的其余部分几乎没有意义。如果您不能使用 真正的 证书,那么正如 Spencer 所说,看看您是否可以设置(或已经拥有)自己的 CA,您可以信任并从那里向您的用户颁发证书。跨度>
      • 是的,这是一个糟糕的情况,但我正在努力减少这种情况。至少我会检查证书中的名称是否与给定的 URL 匹配。
      【解决方案3】:

      如果您可以检查证书,您可以将自己的验证逻辑放入函数 ValidateRemoteCertificate

      System.Net.ServicePointManager.ServerCertificateValidationCallback += (a, b, c, d) =>
      {
           return ValidateRemoteCertificate(a, b, c, d);
      };
      
      private static bool ValidateRemoteCertificate(object sender, X509Certificate certificate,
                  X509Chain chain, SslPolicyErrors policyErrors)
      {
                  if (certificate.Subject.Equals("CN=www.domain.com"))
                      return true;
                  else
                     return policyErrors == SslPolicyErrors.None; 
      
      }
      

      【讨论】:

      • 请不要这样做。这比没有更糟糕,因为它提供了安全的假象,但没有。任何人都可以轻松地创建一个包含字符串“CN=www.domain.com”的证书。
      猜你喜欢
      • 2011-12-03
      • 2017-04-18
      • 2012-11-01
      • 2014-01-26
      • 1970-01-01
      • 2018-06-18
      • 1970-01-01
      • 2021-11-10
      • 2017-08-06
      相关资源
      最近更新 更多