Saltar al contenido

¿Deshabilitar el respaldo de SSL y usar solo TLS para conexiones salientes en .NET? (Mitigación de caniche)

Solución:

Estamos haciendo lo mismo. Para admitir solo TLS 1.2 y no protocolos SSL, puede hacer esto:

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

SecurityProtocolType.Tls es solo TLS 1.0, no todas las versiones de TLS.

Como un lado: si desea verificar que su sitio no permite conexiones SSL, puede hacerlo aquí (no creo que esto se vea afectado por la configuración anterior, tuvimos que editar el registro para obligar a IIS a usar TLS para conexiones entrantes): https://www.ssllabs.com/ssltest/index.html

Para deshabilitar SSL 2.0 y 3.0 en IIS, consulte esta página: https://www.sslshopper.com/article-how-to-disable-ssl-2.0-in-iis-7.html

La respuesta de @Eddie Loeffen parece ser la respuesta más popular a esta pregunta, pero tiene algunos efectos negativos a largo plazo. Si revisa la página de documentación de System.Net.ServicePointManager.SecurityProtocol aquí, la sección de comentarios implica que la fase de negociación solo debe abordar esto (y forzar el protocolo es una mala práctica porque en el futuro, TLS 1.2 también se verá comprometido). Sin embargo, no estaríamos buscando esta respuesta si lo hiciera.

Investigando, parece que se requiere el protocolo de negociación ALPN para llegar a TLS1.2 en la fase de negociación. Tomamos eso como nuestro punto de partida y probamos versiones más nuevas del marco .Net para ver dónde comienza el soporte. Descubrimos que .Net 4.5.2 no admite la negociación con TLS 1.2, pero .Net 4.6 sí.

Por lo tanto, aunque forzar TLS1.2 hará el trabajo ahora, le recomiendo que actualice a .Net 4.6 en su lugar. Dado que se trata de un problema de PCI DSS para junio de 2016, la ventana es corta, pero el nuevo marco es una mejor respuesta.

ACTUALIZACIÓN: Trabajando a partir de los comentarios, construí esto:

ServicePointManager.SecurityProtocol = 0;    
foreach (SecurityProtocolType protocol in SecurityProtocolType.GetValues(typeof(SecurityProtocolType)))
    {
        switch (protocol)
        {
            case SecurityProtocolType.Ssl3:
            case SecurityProtocolType.Tls:
            case SecurityProtocolType.Tls11:
                break;
            default:
                ServicePointManager.SecurityProtocol |= protocol;
            break;
        }
    }

Para validar el concepto, reuní SSL3 y TLS1.2 y ejecuté el código dirigido a un servidor que solo admite TLS 1.0 y TLS 1.2 (1.1 está deshabilitado). Con los protocolos or’d, parece conectarse bien. Si cambio a SSL3 y TLS 1.1, no se pudo conectar. Mi validación usa HttpWebRequest de System.Net y solo llama a GetResponse (). Por ejemplo, probé esto y fallé:

        HttpWebRequest request = WebRequest.Create("https://www.contoso.com/my/web/resource") as HttpWebRequest;
        ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls11;
        request.GetResponse();

mientras esto funcionó:

        HttpWebRequest request = WebRequest.Create("https://www.contoso.com/my/web/resource") as HttpWebRequest;
        ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls12;
        request.GetResponse();

Esto tiene una ventaja sobre forzar TLS 1.2 en que, si el marco .Net se actualiza para que haya más entradas en el Enum, serán compatibles con el código tal cual. Tiene una desventaja sobre el simple uso de .Net 4.6 en que 4.6 usa ALPN y debería admitir nuevos protocolos si no se especifica ninguna restricción.

Editar 4/29/2019: Microsoft publicó este artículo en octubre pasado. Tiene una muy buena sinopsis de su recomendación de cómo se debe hacer esto en las distintas versiones de .net framework.

@watson

En los formularios de Windows está disponible, en la parte superior de la clase poner

  static void Main(string[] args)
    {
        ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
       //other stuff here
    }

Dado que Windows es de un solo subproceso, es todo lo que necesita, en caso de que sea un servicio, debe colocarlo justo encima de la llamada al servicio (ya que no se sabe en qué subproceso estará).

using System.Security.Principal 

también es necesario.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)


Tags : / /

Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *