.Net编程:在SSL自签名证书上验证什么

.Net编程:在SSL自签名证书上验证什么

问题描述:

我无法让用户为他们的服务器创建真正的证书,但是我想做一些安全检查。因此,以下内容太轻松,因为在我阅读时,有没有检查证书。.Net编程:在SSL自签名证书上验证什么

ServicePointManager.ServerCertificateValidationCallback = delegate { return true; }; 

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

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

+0

+1完全同意。除非您可以信任颁发CA,否则证书的其余部分几乎没有意义。如果您不能使用* real * certs,那么正如Spencer所说,请参阅您是否可以设置(或已经拥有)您可以信任的自己的CA,并从那里向您的用户颁发证书。 – 2009-07-27 19:01:37

+0

是的,这是一个糟糕的情况,但我试图让它不那么如此。至少我会检查证书中的名称是否与给定的URL匹配。 – telesphore4 2009-07-27 19:03:23

如果您使用的是自签名证书,那么您应该期望的唯一错误是根(证书颁发者)上的链错误。我会建议像这样的事情,专门陷阱的链错误,让所有其他错误通过。

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; 
} 

,如果你可以检查证书,你可以把自己的验证逻辑功能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; 

}