2010-04-20 39 views
115

estoy recibiendo el siguiente error durante una solicitud de servicio web a un servicio web remoto:C# Ignorar los errores de certificado?

Could not establish trust relationship for the SSL/TLS secure channel. ---> System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure.

todos modos hay que pasar por alto este error y continuar?

Parece que el certificado remoto no está firmado.

El sitio al que me conecto es www.czebox.cz - así que siéntase libre de visitar el sitio, y observe incluso navegadores a través de excepciones de seguridad.

Respuesta

261

Agregue un controlador de validación de certificados. Volviendo true le permite ignorar el error de validación:

ServicePointManager 
    .ServerCertificateValidationCallback += 
    (sender, cert, chain, sslPolicyErrors) => true; 
+5

Esto es incluso más útil de lo que parece a primera vista. Me encontré con el problema de OP mientras usaba Managed Exchanged Web Services (EWS). Pensé que no podía usar esta respuesta ya que no tenía acceso a las llamadas SOAP de bajo nivel que realizaba esa biblioteca administrada. Pero cuando volví a verlo, me di cuenta de que ServicePointManager se sostiene por sí mismo. Entonces, agregué la devolución de llamada anterior antes de inicializar ExchangeService y funcionó como un amuleto. –

+0

@PeterLillevold Tuve un SSL autofirmado para las pruebas internas, hasta donde veo esto ignora los errores, ¡era muy difícil de encontrar sin orientación! – Pogrindis

+0

@Pogrindis: sí, un certificado autofirmado (ya que no es un certificado de confianza) no aprobará la validación del certificado. Si se devuelve 'true' en la devolución de llamada, se ignorarán los errores de validación, lo que permitirá completar las llamadas al sitio utilizando el certificado que no es de confianza. –

24

La razón está fallando no es porque no está firmado, pero debido a que el certificado raíz no es de confianza por su cliente. En lugar de desactivar la validación de SSL, un enfoque alternativo sería agregar el certificado de CA raíz a la lista de CA en las que confía su aplicación.

Este es el certificado CA raíz de que su aplicación actualmente no se fía:

----- BEGIN CERTIFICATE ----- MIIFnDCCBISgAwIBAgIBZDANBgkqhkiG9w0BAQsFADBbMQswCQYDVQQGEwJDWjEs MCoGA1UECgwjxIxlc2vDoSBwb8WhdGEsIHMucC4gW0nEjCA0NzExNDk4M10xHjAc BgNVBAMTFVBvc3RTaWdudW0gUm9vdCBRQ0EgMjAeFw0xMDAxMTkwODA0MzFaFw0y NTAxMTkwODA0MzFaMFsxCzAJBgNVBAYTAkNaMSwwKgYDVQQKDCPEjGVza8OhIHBv xaF0YSwgcy5wLiBbScSMIDQ3MTE0OTgzXTEeMBwGA1UEAxMVUG9zdFNpZ251bSBS b290IFFDQSAyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoFz8yBxf 2gf1uN0GGXknvGHwurpp4Lw3ZPWZB6nEBDGjSGIXK0Or6Xa3ZT + TVDTeUUjT133G 7Vs51D6z/ShWy + 9T7a1f6XInakewyFj8PT0EdZ4tAybNYdEUO/dShg2WvUyfZfXH 0jmmZm6qUDy0VfKQfiyWchQRi/Ax6zXaU2 + X3hXBfvRMr5l6zgxYVATEyxCfOLM9 a5U6lhpyCDf2Gg6dPc5Cy6QwYGGpYER1fzLGsN9stdutkwlP13DHU1Sp6W5ywtfL owYaV1bqOOdARbAoJ7q8LO6EBjyIVr03mFusPaMCOzcEn3zL5XafknM36Vqtdmqz IWR + 3URAUgqE0wIDAQABo4ICaTCCAmUwgaUGA1UdHwSBnTCBmjAxoC + gLYYraHR0 cDovL3d3dy5wb3N0c2lnbnVtLmN6L2NybC9wc3Jvb3RxY2EyLmNybDAyoDCgLoYs aHR0cDovL3d3dzIucG9zdHNpZ251bS5jei9jcmwvcHNyb290cWNhMi5jcmwwMaAv oC2GK2h0dHA6Ly9wb3N0c2lnbnVtLnR0Yy5jei9jcmwvcHNyb290cWNhMi5jcmww gfEGA1UdIASB6TCB5jCB4wYEVR0gADCB2jCB1wYIKwYBBQUHAgIwgcoagcdUZW50 byBrdmFsaWZpa292YW55IHN5c3RlbW92eSBjZXJ0aWZpa2F0IGJ5bCB2eWRhbiBw b2RsZSB6YWtvbmEgMjI3LzIwMDBTYi4gYSBuYXZhem55Y2ggcHJlZHBpc3UvVGhp cyBxdWFsaWZpZWQgc3lzdGVtIGNlcnRpZmljYXRlIHdhcyBpc3N1ZWQgYWNjb3Jk aW5nIHRvIExhdyBObyAyMjcvMjAwMENvbGwuIGFuZCByZWxhdGVkIHJlZ3VsYXRp b25zMBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQW BBQVKYzFRWmruLPD6v5LuDHY3PDndjCBgwYDVR0jBHwweoAUFSmMxUVpq7izw + r + S7gx2Nzw53ahX6RdMFsxCzAJBgNVBAYTAkNaMSwwKgYDVQQKDCPEjGVza8OhIHBv xaF0YSwgcy5wLiBbScSMIDQ3MTE0OTgzXTEeMBwGA1UEAxMVUG9zdFNpZ251bSBS b290IFFDQSAyggFkMA0GCSqGSIb3DQEBCwUAA4IBAQBeKtoLQKFqWJEgLNxPbQNN 5OTjbpOTEEkq2jFI0tUhtRx // 6zwuqJCzfO/KqggUrHBca + GV/qXcNzNAlytyM71 FMV/VwgL9gBHTN/IFIw100JbciI23yFQTdF/UoEfK/m + IFfirxSRi8LRERdXHTEb vwxMXIzZVXloW vX64UwWtf4Tvw5bAoPj0O1Z2ly4aMTAT2a + y + z184UhuZ/oGyMw eIakmFM7M7RrNki507jiSLTzuaFMCpyWOX7ULIhzY6xKdm5iQLjTvExn2JTvVChF Y + Juu/G0zAdLyeU4vaXdQm1A8AEiJPTd0Z9LAxL6Sq2iraLNN36 + nyek/ts3mPLL

----- END CERTIFICATE -----

Puede decodificar y ver el certificado mediante

this certificate decoder o another certificate decoder

23

IgnoreBadCertificates Método:

//I use a method to ignore bad certs caused by misc errors 
IgnoreBadCertificates(); 

// after the Ignore call i can do what ever i want... 
HttpWebRequest request_data = System.Net.WebRequest.Create(urlquerystring) as HttpWebRequest; 

/* 
and below the Methods we are using... 
*/ 

/// <summary> 
/// Together with the AcceptAllCertifications method right 
/// below this causes to bypass errors caused by SLL-Errors. 
/// </summary> 
public static void IgnoreBadCertificates() 
{ 
    System.Net.ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(AcceptAllCertifications); 
} 

/// <summary> 
/// In Short: the Method solves the Problem of broken Certificates. 
/// Sometime when requesting Data and the sending Webserverconnection 
/// is based on a SSL Connection, an Error is caused by Servers whoes 
/// Certificate(s) have Errors. Like when the Cert is out of date 
/// and much more... So at this point when calling the method, 
/// this behaviour is prevented 
/// </summary> 
/// <param name="sender"></param> 
/// <param name="certification"></param> 
/// <param name="chain"></param> 
/// <param name="sslPolicyErrors"></param> 
/// <returns>true</returns> 
private static bool AcceptAllCertifications(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certification, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors) 
{ 
    return true; 
} 
+1

Tuve que agregar una línea más para que esto funcione con mi código (estoy usando websocket4net). System.Net.ServicePointManager.CheckCertificateRevocationList = false; Inmediatamente después de configurar la devolución de llamada de validación del certificado del servidor. – kalyanmysore

+1

Gracias por proporcionar un ejemplo de código completo que fue perfectamente claro y fácil de comprender e implementar. Esta debería ser la respuesta aceptada. – Jake

1

Ampliar aún más la publicación de BIGNUM - Lo ideal es que quiera una solución que simule las condiciones que verá en producción y modificar su código no hará eso y podría ser peligroso si olvida tomar el código antes lo despliegas

Necesitará un certificado autofirmado de algún tipo. Si sabe lo que está haciendo, puede utilizar el BIGNUM binario publicado, pero si no puede ir a buscar el certificado. Si está utilizando IIS Express ya tendrá uno de estos, solo tendrá que encontrarlo. Abra Firefox o el navegador que desee e ingrese a su sitio web de desarrollo.Debería poder ver la información del certificado desde la barra de URL y, dependiendo de su navegador, debería poder exportar el certificado a un archivo.

A continuación, abra MMC.exe y agregue el complemento Certificado. Importe su archivo de certificado en la tienda Autoridades de certificación de raíz de confianza y eso es todo lo que necesita. Es importante asegurarse de que vaya a esa tienda y no a otra tienda como 'Personal'. Si no está familiarizado con MMC o certificados, hay numerosos sitios web con información sobre cómo hacer esto.

Ahora, su computadora como un todo confiará implícitamente en cualquier certificado que se haya generado y no necesitará agregar código para manejar esto especialmente. Cuando pase a producción, continuará funcionando siempre que tenga un certificado válido instalado allí. No haga esto en un servidor de producción; sería malo y no funcionaría para ningún otro cliente que no sea el servidor.

3

Para desactivar la validación de ssl cert en la configuración del cliente.

<behaviors> 
    <endpointBehaviors> 
     <behavior name="DisableSSLCertificateValidation"> 
     <clientCredentials> 
      <serviceCertificate> 
       <sslCertificateAuthentication certificateValidationMode="None" /> 
       </serviceCertificate> 
      </clientCredentials> 
     </behavior> 
2

Si está utilizando sockets directamente y se autentifica como el cliente, entonces el método de devolución de llamada Administrador de Service Point no funcionará. Esto es lo que funcionó para mí. FAVOR DE UTILIZAR CON FINES DE PRUEBA SOLAMENTE.

var activeStream = new SslStream(networkStream, false, (a, b, c, d) => { return true; }); 
await activeStream.AuthenticateAsClientAsync("computer.local"); 

La clave aquí, es proporcionar la devolución de llamada de validación de certificados a distancia justo en el constructor de la secuencia SSL.

13

Permitir todos los certificados es muy potente, pero también podría ser peligroso. Si solo desea permitir certificados válidos más ciertos certificados, se podría hacer así.

System.Net.ServicePointManager.ServerCertificateValidationCallback += delegate (
    object sender, 
    X509Certificate cert, 
    X509Chain chain, 
    SslPolicyErrors sslPolicyErrors) 
{ 
    if (sslPolicyErrors == SslPolicyErrors.None) 
    { 
     return true; //Is valid 
    } 

    if (cert.GetCertHashString() == "99E92D8447AEF30483B1D7527812C9B7B3A915A7") 
    { 
     return true; 
    } 

    return false; 
}; 

Actualización:

Cómo llegar cert.GetCertHashString() valor en Chrome:

Haga clic en Secure o Not Secure en la barra de direcciones.

enter image description here

enter image description here

A continuación, haga clic en el certificado -> Detalles -> Huella digital y copia el valor. Recuerde hacer cert.GetCertHashString().ToLower().

enter image description here

+1

Esta debería ser la respuesta aceptada, solo un poco más de trabajo pero mucho menos peligrosa. ¡Gracias! –

+2

@MiguelVeloso Totalmente de acuerdo. Esto permite omitir la verificación (con suerte) de uno o dos certificados sin comprometer por completo la seguridad. –

+0

¿CÓMO puedo obtener 'Hash String' de un certificado? – Kiquenet

1

Este código trabajó para mí. Tuve que agregar TLS2 porque eso es lo que estaba usando la URL que me interesa.

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; 
ServicePointManager.ServerCertificateValidationCallback += 
    (sender, cert, chain, sslPolicyErrors) => { return true; }; 
using (var client = new HttpClient()) 
{ 
    client.BaseAddress = new Uri(UserDataUrl); 
    client.DefaultRequestHeaders.Accept.Clear(); 
    client.DefaultRequestHeaders.Accept.Add(new 
     MediaTypeWithQualityHeaderValue("application/json")); 
    Task<string> response = client.GetStringAsync(UserDataUrl); 
    response.Wait(); 

    if (response.Exception != null) 
    { 
     return null; 
    } 

    return JsonConvert.DeserializeObject<UserData>(response.Result); 
} 
Cuestiones relacionadas