2011-10-08 19 views
7

He generado una CA y varios certificados (firmados por CA) usando OpenSSL y tengo un cliente y servidor .NET/C# ambos usando SslStream, cada uno con sus propios certificados/claves. la autenticación mutua está habilitada y la revocación está deshabilitada.Verificar el servidor remoto X509Certificate utilizando el archivo de certificado CA

estoy usando RemoteCertificateValidationCallback para SslStream para validar el certificado del servidor remoto y esperaba que sólo podía cargar el certificado público de la CA (como un archivo) en el programa y utilizarlo para comprobar el certificado de control remoto en lugar de instalar realmente el CA en el Windows Certificate Store. El problema es que el X509Chain no mostrará nada más a menos que instale la CA en la tienda, o el shell de Windows CryptoAPI cuando abro una versión PEM de uno de los certificados.

Mi pregunta es, ¿cómo puedo comprobar un certificado ha sido firmado por mi específica CA sólo mediante el uso de archivos certificado público de la CA sin utilizar el almacén de certificados de Windows o WCF cuando no parecen RemoteCertificateValidationCallback, X509Certificate y X509Chain para dar algo con lo que trabajar?

+1

No entiendo por qué agregar el certificado de CA a Windows Store hace que X509Chain lo muestre en la cadena, pero si no lo hago no es parte de él. ¿Hay alguien para agregar el certificado de CA a la cadena dentro de RemoteCertificateValidationCallback? – user985122

+0

Todavía no puedo encontrar una respuesta a esto :( – user985122

Respuesta

5

Debido a que el certificado de CA no está en el almacén de certificados raíz, tendrá dentro del RemoteCertificateValidationCallback() un indicador de error de SslPolicyErrors.RemoteCertificateChainErrors; una posibilidad es validar explícitamente la cadena de certificados contra su propia X509Certificate2Collection, ya que no está utilizando la tienda local.

if (sslPolicyErrors == SslPolicyErrors.RemoteCertificateChainErrors) 
{ 
    X509Chain chain0 = new X509Chain(); 
    chain0.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; 
    // add all your extra certificate chain 
    chain0.ChainPolicy.ExtraStore.Add(new X509Certificate2(PublicResource.my_ca)); 
    chain0.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority; 
    isValid = chain0.Build((X509Certificate2)certificate); 
} 

También puede volver a utilizar la cadena aprobada en la devolución de llamada, agregar su certificado (s) adicional en el colección ExtraStore, y validar con la bandera AllowUnknownCertificateAuthority que es necesaria ya que se agrega que no se confía certificado (s) a la cadena.

También puede evitar que el error original mediante la adición de programación el certificado de CA en el almacén raíz de confianza (por supuesto, se abre una ventana emergente, ya que es un gran problema de seguridad globalmente añadir una nueva CA raíz de confianza):

var store = new X509Store(StoreName.Root, StoreLocation.CurrentUser); 
store.Open(OpenFlags.ReadWrite); 
X509Certificate2 ca_cert = new X509Certificate2(PublicResource.my_ca); 
store.Add(ca_cert); 
store.Close(); 
+0

Otra posibilidad es utilizar la biblioteca 'BouncyCastle' para construir la cadena de certificados y validar la confianza. Las opciones son claras y los errores son fáciles de entender. –

+0

Consulte la respuesta http : //stackoverflow.com/a/27310276/1038496 aquí para una verificación adecuada de su propia CA. El método anterior aceptará todas las CA (sin verificaciones de validez). – Zoka

1

¿Cómo puedo comprobar un certificado ha sido firmado por mi específica CA sólo mediante el uso de archivos certificado público de la CA sin utilizar el almacén de certificados de Windows o WCF cuando no parecen RemoteCertificateValidationCallback, X509Certificate y X509Chain darme nada para trabajar ¿con?

El siguiente código evitará los almacenes de certificados de Windows y validará la cadena. Es un poco diferente al código de JB, especialmente en el uso de banderas. El código siguiente no requiere AllowUnknownCertificateAuthority (pero sí usa X509RevocationMode.NoCheck ya que no tengo una CRL).

El nombre de la función no es importante. Debajo, VerifyServerCertificate es la misma devolución de llamada que RemoteCertificateValidationCallback en la clase SslStream. También puede usarlo para el ServerCertificateValidationCallback en ServicePointManager.

static bool VerifyServerCertificate(object sender, X509Certificate certificate, 
    X509Chain chain, SslPolicyErrors sslPolicyErrors) 
{ 
    try 
    { 
     String CA_FILE = "ca-cert.der"; 
     X509Certificate2 ca = new X509Certificate2(CA_FILE); 

     X509Chain chain2 = new X509Chain(); 
     chain2.ChainPolicy.ExtraStore.Add(ca); 

     // Check all properties 
     chain2.ChainPolicy.VerificationFlags = X509VerificationFlags.NoFlag; 

     // This setup does not have revocation information 
     chain2.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; 

     // Build the chain 
     chain2.Build(new X509Certificate2(certificate)); 

     // Are there any failures from building the chain? 
     if (chain2.ChainStatus.Length == 0) 
      return true; 

     // If there is a status, verify the status is NoError 
     bool result = chain2.ChainStatus[0].Status == X509ChainStatusFlags.NoError; 
     Debug.Assert(result == true); 

     return result; 
    } 
    catch (Exception ex) 
    { 
     Console.WriteLine(ex); 
    } 

    return false; 
} 

tengo no descubierto la manera de utilizar esta cadena (chain2 a continuación) por defecto de tal manera que no hay necesidad de que la devolución de llamada.Es decir, instálelo en el socket ssl y la conexión "solo funcionará". Y tengo no descubrí cómo instalarlo de modo que pase a la devolución de llamada. Es decir, tengo que construir la cadena para cada invocación de la devolución de llamada. Creo que estos son defectos arquitectónicos en .Net, pero me podría estar perdiendo algo obvio.

+0

Se ve bien. El 'chain2' será la lista de confianza de certificado entre el certificado probado y el certificado raíz. Hoy en día, es posible que desee utilizar la biblioteca BouncyCastle si realiza operaciones avanzadas en los certificados. –

Cuestiones relacionadas