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

StackOverflow https://stackoverflow.com/questions/703272

  •  22-08-2019
  •  | 
  •  

Pregunta

Tengo una llamada de servicio web simple, generada por una aplicación de Windows .NET (C#) 2.0, a través del proxy de 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 ejecuta.

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

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

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

¿Dónde miro?¿Podría ser esto un problema de seguridad entre Windows y .NET exclusivo de esta instalación?Si es así, ¿dónde establezco relaciones de confianza?¡Estoy perdido!

¿Fue útil?

Solución

Pensamientos (basado en el dolor en el pasado):

  • ¿tiene DNS y la línea de visión directa con el servidor?
  • ¿Está utilizando el nombre correcto del certificado?
  • es el certificado sigue siendo válido?
  • es un equilibrador de carga mal configurado ensuciar las cosas?
  • ¿el nuevo servidor máquina tiene el reloj ajustado correctamente (es decir, para que el tiempo UTC es correcta [ignorar hora local, es en gran medida irrelevante]) - esto ciertamente importa para WCF, por lo que puede afectar jabón normal?
  • ¿hay un problema de la cadena de certificados de confianza? si navega desde el servidor al servicio de jabón, se puede obtener SSL?
  • Relacionado con lo anterior - se ha instalado el certificado en el lugar correcto? (Puede que tenga una copia de las autoridades de certificación raíz de confianza)
  • se ha ajustado correctamente proxy a nivel de la máquina del servidor? (Que diferente para el proxy del usuario); ver proxycfg para XP / 2003 (no estoy seguro sobre Vista, etc)

Otros consejos

Los siguientes fragmentos se solucionará el caso en el que hay algo mal con el certificado SSL en el servidor al que está llamando. Por ejemplo, puede ser autofirmado o el nombre de host entre el certificado y el servidor pueden no coincidir.

Esto es peligroso si está llamando a un servidor fuera de su control directo, ya que ya no puede ser tan seguro de que usted está hablando con el servidor cree que está conectado. Sin embargo, si se trata de servidores internos y obtener un certificado de "correcta" no es práctico, utilice el siguiente para indicar el servicio web de ignorar los problemas de certificado y con valor soldado.

Las dos primeras expresiones lambda uso, el tercero utiliza código regular. El primero acepta cualquier certificado. Los dos últimos, al menos, compruebe que el nombre de host del certificado es el que usted espera.
... espero que le sea ú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 = cert.Subject.Contains("YourServerName");
    return result;
}

El muy simple "coger todos" solución es la siguiente:

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

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

Personalmente, me gusta la siguiente solución más:

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

... a continuación, antes de hacer la solicitud recibiendo el error, haga lo siguiente

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

Encontrados este tras consultar Solución de Lucas

Si está utilizando Windows 2003, puede intentar esto:

Abra la consola de administración de Microsoft (Inicio --> Ejecutar --> mmc.exe);

Elija Archivo --> Agregar o quitar complemento;

En la pestaña Independiente, elija Agregar;

Elija los certificados Snap-In y haga clic en Agregar;

En el asistente, elija el equipo Cuenta y, a continuación, elija Local Ordenador.Presione Finalizar para finalizar el hechicero;

Cierre el cuadro de diálogo Agregar o quitar complemento;

Vaya a Certificados (Local Computadora) y elija una tienda para importación:

Si tiene el certificado de CA raíz para la empresa que emitió el certificado, elija Raíz de confianza Autoridades de Certificación;

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

Haga clic con el botón derecho en la tienda y elija todas las tareas-> Importar

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

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

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

Si no wa no a confiar ciegamente en todo el mundo y hacer una excepción confianza sólo para determinados hosts la siguiente solución es más apropiado.

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

A continuación, sólo llamar Ssl.EnableTrustedHosts cuando su aplicación se inicia.

SSL Herramienta de diagnóstico

de Microsoft puede ser capaz de ayudar a identificar el problema.

Actualizar el enlace se ha fijado ahora.

Lucas escribió un buen artículo sobre este .. bastante sencillo .. le daría prueba

Solución de Lucas

Razón (cita de su artículo (menos maldición)) " ..  El problema con el código anterior es que no funciona si el certificado no es válido. ¿Por qué estaría publicar en una página web con SSL y el certificado no válido? Porque soy barato y no me sentía como el pago de Verisign o uno de los otros ** - * s para un CERT a mi caja de prueba, así que sí lo firmó. Cuando envié la solicitud Tengo una excepción preciosa lanzada contra mí:

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

No sé ustedes, pero a mí esa excepción parecía algo que podría ser causado por un error tonto en mi código que estaba causando el POST falle. Así que seguí buscando, y ajustar y hacer todo tipo de cosas extrañas. Sólo después busqué en Google la cosa *** n descubrí que el comportamiento predeterminado después de encontrarse con un certificado SSL válido es lanzar esta misma excepción. .. "

Yo sólo encontré con este problema. Mi resolución fue actualizar la hora del sistema mediante la sincronización manualmente a los servidores de tiempo. Para ello se puede:

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

En mi caso esto se sincroniza de forma incorrecta por lo que tuvo que hacer clic varias veces antes de que se actualiza correctamente. Si se sigue actualizando de forma incorrecta incluso se puede tratar de usar un servidor de tiempo diferente del servidor desplegable.

He tenido un problema similar en aplicación .NET en Internet Explorer.

He resuelto el problema de añadir el certificado (certificado de clase 3 de VeriSign en mi caso) a los certificados de editores de confianza.

Go to Internet Options-> Content -> Publishers and import it

Usted puede obtener el certificado si se exporta a partir de:

Internet Options-> Content -> Certificates -> Intermediate Certification Authorities -> VeriSign Class 3 Public Primary Certification Authority - G5

gracias

Prueba esto:

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

Tenga en cuenta que usted tiene que trabajar por lo menos con 4,5 .NET Framework

tuve este error se ejecuta contra un servidor web con URL como:

a.b.domain.com

pero no había certificado para él, así que me dieron un DNS llamado

a_b.domain.com

Simplemente poniendo pista a esta solución aquí, ya que esto llegó hasta la parte superior de Google.

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

  • Abra la URL de punto final de Internet Explorer.
  • Haga clic en el error de certificado (icono rojo en la barra de direcciones)
  • Haga clic en Ver certificados.
  • Coge la expedido a:. "Nombre" y sustituir la dirección IP o el nombre que estábamos usando y conseguir el error de este "nombre"

Trate de nuevo :). Gracias

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

Esto es lo que terminé haciendo para conseguir que funcione:

  • En mi sitio en la sección 'Enlaces ...' a la derecha en IIS, he tenido que añadir el 'https' enlace al puerto 443 y seleccione "IIS expreso Developement Certificado".

  • En mi sitio en la sección 'Configuración avanzada ...' a la derecha que tenía que cambiar los 'Protocolos habilitados' de "http" a "https".

  • En el icono 'Configuración SSL' he seleccionado 'Aceptar' para certificados de cliente.

  • Luego tuve que reciclar el grupo de aplicaciones.

  • También tenía que importar el certificado de host local en mi tienda utilizando mmc.exe personal.

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

Mi solución (VB.Net, la "puesta en escena" (UAT) de esta aplicación tiene que trabajar con la "puesta en escena" certificado, pero no afecta a las solicitudes una vez que están en el sitio en vivo):

    ...
        Dim url As String = ConfigurationManager.AppSettings("APIURL") & "token"
        If url.ToLower().Contains("staging") Then
           System.Net.ServicePointManager.ServerCertificateValidationCallback = AddressOf AcceptAllCertifications
        End If
    ...

    Private  Function AcceptAllCertifications(ByVal sender As Object, ByVal certification As System.Security.Cryptography.X509Certificates.X509Certificate, ByVal chain As System.Security.Cryptography.X509Certificates.X509Chain, ByVal sslPolicyErrors As System.Net.Security.SslPolicyErrors) As Boolean
        Return True
    End Function

Si no funciona mal sertificate, cuando ServerCertificateValidationCallback return true; Mi código ServerCertificateValidationCallback:

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

Mi código que el ServerCertificateValidationCallback ejecutar impedido:

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

OnValidateCertificateError función:

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

Me discapacitados código CertificateValidation y ServerCertificateValidationCallback funcionando muy bien

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top