No se pudo establecer una relación de confianza para el canal seguro SSL / TLS – SOAP

Tengo una llamada de servicio web simple, generada por una aplicación de Windows .NET (C #) 2.0, a través del proxy del servicio web generado por Visual Studio, para un servicio web también escrito en C # (2.0). Esto ha funcionado durante varios años y continúa haciéndolo en la docena de lugares donde se está ejecutando.

Una nueva instalación en un nuevo sitio tiene un problema. Al intentar invocar el servicio web, falla con el mensaje que dice:

No se pudo establecer una relación de confianza para el canal seguro SSL / TLS

La URL del servicio web usa SSL (https: //), pero esto ha estado funcionando durante mucho tiempo (y continúa haciéndolo) desde muchas otras ubicaciones.

¿Dónde me veo? ¿Podría ser este un problema de seguridad entre Windows y .NET que es exclusivo de esta instalación? Si es así, ¿dónde configuro las relaciones de confianza? ¡Estoy perdido!

Pensamientos (basados ​​en el dolor en el pasado):

  • ¿tiene DNS y línea de visión para el servidor?
  • ¿Estás usando el nombre correcto del certificado?
  • ¿El certificado sigue siendo válido?
  • es un balanceador de carga mal configurado arruinando las cosas?
  • ¿tiene la máquina del servidor nuevo el reloj configurado correctamente (es decir, para que la hora UTC sea correcta [ignore la hora local, es en gran parte irrelevante]) – esto ciertamente importa para WCF, por lo que puede afectar el SOAP regular?
  • ¿Hay algún problema en la cadena de confianza del certificado? Si navega desde el servidor hasta el servicio de soap, ¿puede obtener SSL?
  • relacionado con lo anterior: ¿el certificado se ha instalado en la ubicación correcta? (es posible que necesite una copia en Autoridades de certificación raíz de confianza)
  • ¿El proxy a nivel de máquina del servidor está configurado correctamente? (que es diferente al proxy del usuario); vea proxycfg para XP / 2003 (no estoy seguro acerca de Vista, etc.)

Los siguientes fragmentos corregirán el caso en el que exista algún problema con el certificado SSL en el servidor al que está llamando. Por ejemplo, puede estar autofirmado o el nombre de host entre el certificado y el servidor puede no coincidir.

Esto es peligroso si llama a un servidor fuera de su control directo, ya que ya no puede estar tan seguro de que está hablando con el servidor que cree que está conectado. Sin embargo, si está tratando con servidores internos y obtener un certificado “correcto” no es práctico, use lo siguiente para decirle al servicio web que ignore los problemas del certificado y valientemente soldado.

Los primeros dos usan expresiones lambda, el tercero usa código regular. El primero acepta cualquier certificado. Los dos últimos al menos verifican que el nombre de host en el certificado sea el que espera.
… espero que lo encuentres útil

//Trust all certificates System.Net.ServicePointManager.ServerCertificateValidationCallback = ((sender, certificate, chain, sslPolicyErrors) => true); // trust sender System.Net.ServicePointManager.ServerCertificateValidationCallback = ((sender, cert, chain, errors) => cert.Subject.Contains("YourServerName")); // validate cert by calling a function ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(ValidateRemoteCertificate); // callback used to validate the certificate in an SSL conversation private static bool ValidateRemoteCertificate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors policyErrors) { bool result = false; if (cert.Subject.ToUpper().Contains("YourServerName")) { result = true; } return result; } 

La muy simple solución “atrapa todo” es esta:

 System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate { return true; }; 

La solución de sebastian-castaldi es un poco más detallada.

A mí personalmente me gusta más la siguiente solución:

 using System.Security.Cryptography.X509Certificates; using System.Net.Security; 

… luego, antes de que solicite obtener el error, haga lo siguiente

 System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { return true; }; 

Encontré esto después de consultar la Solución de Luke

Si está usando Windows 2003, puede intentar esto:

Abra Microsoft Management Console (Inicio -> Ejecutar -> mmc.exe);

Elija Archivo -> Agregar / Eliminar complemento;

En la pestaña Independiente, elija Agregar;

Elija el complemento Certificados y haga clic en Agregar;

En el asistente, elija la Cuenta del equipo y luego elija Computadora local. Presione Finalizar para finalizar el asistente;

Cierre el cuadro de diálogo Agregar / Eliminar complemento;

Navegue a Certificados (computadora local) y elija una tienda para importar:

Si tiene el certificado de Root CA para la compañía que emitió el certificado, elija Trusted Root Certification Authorities;

Si tiene el certificado para el servidor en sí, elija Otras personas

Haga clic derecho en la tienda y seleccione Todas las tareas -> Importar

Siga el asistente y proporcione el archivo de certificado que tiene;

Después de eso, simplemente reinicie IIS e intente llamar al servicio web nuevamente.

Referencia: http://www.outsystems.com/NetworkForums/ViewTopic.aspx?Topic=Web-Services:-Could-not-establish-trust-relationship-for-the-SSL/TLS-

Si no quiere confiar ciegamente en todos y hacer una excepción de confianza solo para ciertos hosts, la siguiente solución es más apropiada.

 public static class Ssl { private static readonly string[] TrustedHosts = new[] { "host1.domain.com", "host2.domain.com" }; public static void EnableTrustedHosts() { ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, errors) => { if (errors == SslPolicyErrors.None) { return true; } var request = sender as HttpWebRequest; if (request != null) { return TrustedHosts.Contains(request.RequestUri.Host); } return false; }; } } 

Luego solo llame a Ssl.EnableTrustedHosts cuando se inicie su aplicación.

La herramienta de diagnóstico SSL de Microsoft puede ayudar a identificar el problema.

ACTUALIZAR el enlace ha sido arreglado ahora.

Luke escribió un artículo bastante bueno sobre esto … bastante sencillo … pruébalo

La solución de Luke

Motivo (cita de su artículo (menos maldiciones)) “… El problema con el código anterior es que no funciona si su certificado no es válido. ¿Por qué estaría publicando en una página web con un certificado SSL no válido? Soy barato y no tenía ganas de pagar Verisign o uno de los otros ** – * s por un certificado en mi casilla de prueba, así que lo firmé. Cuando envié la solicitud, recibí una hermosa excepción:

System.Net.WebException La conexión subyacente estaba cerrada. No se pudo establecer una relación de confianza con el servidor remoto.

No sé ustedes, pero para mí esa excepción parecía algo que sería causado por un error tonto en mi código que estaba causando que fallara el POST. Así que seguí buscando, retocando y haciendo todo tipo de cosas raras. Solo después de buscar en Google lo que descubrí, el comportamiento predeterminado después de encontrar un certificado SSL no válido arroja esta misma excepción. .. ”

Acabo de encontrar este problema. Mi resolución fue actualizar la hora del sistema mediante la sincronización manual con los servidores horarios. Para hacer esto puedes:

  • Haga clic derecho en el reloj en la barra de tareas
  • Seleccione Adjust Date/Time
  • Seleccione la pestaña Internet Time
  • Haz clic en Change Settings
  • Selecciona Update Now

En mi caso, esto se sincronizaba incorrectamente, así que tuve que hacer clic varias veces antes de que se actualizara correctamente. Si continúa actualizándose incorrectamente, puede incluso intentar usar un servidor horario diferente del menú desplegable del servidor.

Tuve un problema similar en la aplicación .NET en Internet Explorer.

Resolví el problema de agregar el certificado (certificado de VeriSign Class 3 en mi caso) a certificados de editores de confianza.

Vaya a Opciones de Internet-> Contenido-> Editores e impórtelo

Puede obtener el certificado si lo exporta desde:

Opciones de Internet-> Contenido -> Certificados -> Autoridades de Certificación Intermedias -> Autoridad de Certificación Primaria Pública VeriSign Clase 3 – G5

Tuve este error ejecutándose contra un servidor web con url como:

 abdomain.com 

pero no había certificado para eso, así que recibí un DNS llamado

 a_b.domain.com 

Solo puse una pista sobre esta solución aquí ya que esta apareció arriba en google.

Para aquellos que están teniendo este problema a través del lado del cliente VS una vez añadieron con éxito una referencia de servicio e intentan ejecutar la primera llamada obtuvieron esta excepción: “La conexión subyacente se cerró: No se pudo establecer una relación de confianza para el canal seguro SSL / TLS” está utilizando (como mi caso) una URL de punto final con la dirección IP y obtuvo esta excepción, entonces probablemente debería volver a agregar la referencia de servicio siguiendo estos pasos:

  • Abra la URL del punto final en Internet Explorer.
  • Haga clic en el error de certificado (icono rojo en la barra de direcciones)
  • Haga clic en Ver certificados.
  • Agarre el emitido a: “nombre” y reemplace la dirección IP o el nombre que estábamos usando y obteniendo el error para este “nombre”.

Inténtalo de nuevo :). Gracias

En mi caso, estaba tratando de probar SSL en mi entorno de Visual Studio usando IIS 7.

Esto es lo que terminé haciendo para que funcione:

  • Debajo de mi sitio en la sección ‘Vinculaciones …’ a la derecha en IIS, tuve que agregar el enlace ‘https’ al puerto 443 y seleccionar ‘Certificado de desarrollo IIS Express’.

  • Debajo de mi sitio en la sección “Configuración avanzada …” a la derecha tuve que cambiar los “Protocolos habilitados” de “http” a “https”.

  • Debajo del ícono ‘Configuración SSL’, seleccioné ‘Aceptar’ para los certificados del cliente.

  • Luego tuve que reciclar el grupo de aplicaciones.

  • También tuve que importar el certificado del host local en mi tienda personal usando mmc.exe.

Mi archivo web.config ya estaba configurado correctamente, así que después de haber resuelto todo lo anterior, pude continuar mis pruebas.

Prueba esto:

 System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12; 

Tenga en cuenta que debe trabajar al menos con 4.5 .NET framework

Si no funciona, sertificate, cuando ServerCertificateValidationCallback devuelve true; Mi ServerCertificateValidationCallback code:

 ServicePointManager.ServerCertificateValidationCallback += delegate { LogWriter.LogInfo("Проверка сертификата отключена, на уровне ServerCertificateValidationCallback"); return true; }; 

Mi código que impidió ejecutar ServerCertificateValidationCallback:

  if (!(ServicePointManager.CertificatePolicy is CertificateValidation)) { CertificateValidation certValidate = new CertificateValidation(); certValidate.ValidatingError += new CertificateValidation.ValidateCertificateEventHandler(this.OnValidateCertificateError); ServicePointManager.CertificatePolicy = certValidate; } 

Función OnValidateCertificateError:

 private void OnValidateCertificateError(object sender, CertificateValidationEventArgs e) { string msg = string.Format(Strings.OnValidateCertificateError, e.Request.RequestUri, e.Certificate.GetName(), e.Problem, new Win32Exception(e.Problem).Message); LogWriter.LogError(msg); //Message.ShowError(msg); } 

Inhabilité el código de CertificateValidation y ServerCertificateValidationCallback funcionando muy bien