2009-07-27 17 views
5

No puedo conseguir que los usuarios creen certificados reales para sus servidores, pero me gustaría hacer algunas comprobaciones de seguridad. Entonces, el siguiente es demasiado claro porque, mientras lo leo, hay no comprobando los certs.Programación .Net: qué validar en un certificado SSL autofirmado

ServicePointManager.ServerCertificateValidationCallback = delegate { return true; }; 

¿Qué recomienda que haga que los clientes verifiquen el certificado x509? Dado que estoy usando un lenguaje .NET (C#/f #).

Respuesta

4

Si no puede lograr que los clientes creen certs reales, al menos debería intentar que creen certs utilizando su servidor. Luego puede verificar que el certificado sea válido o al menos de su CA porque sabrá si su CA ha sido comprometida. Si confías en todas y cada una de las CA, realmente no hay nada que valga la pena verificar.

+0

+1 totalmente de acuerdo. A menos que pueda confiar en la CA emisora, entonces el resto del certificado no tiene sentido. Si no puede usar certificaciones * reales *, entonces, como dice Spencer, vea si puede configurar (o ya tiene) su CA en la que puede confiar y emitir certificados a sus usuarios desde allí. –

+0

Sí, esta es una mala situación, pero estoy intentando que sea menos. Por lo menos, verificaré que el nombre en el certificado coincida con la URL dada. – telesphore4

5

Si está utilizando certificados autofirmados, el único error que debe esperar es un error de cadena en la raíz (Cert. Emisor). Sugeriría algo como esto que atrape ese error de cadena específicamente y deje que todos los demás errores fracasen.

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

si se puede comprobar certs que podría poner su propia lógica de validación en la función 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; 

} 
+0

Por favor, no hagas esto. Esto es peor que nada porque proporciona la ilusión de seguridad pero aún no tiene ninguna. Cualquiera puede crear trivialmente un cert con la cadena "CN = www.domain.com" en él. – Daryl

Cuestiones relacionadas