Default SecurityProtocol en .NET 4.5

¿Cuál es el protocolo de seguridad predeterminado para comunicarse con servidores que admiten hasta TLS 1.2 ? Will .NET por defecto, elija el protocolo de seguridad más alto compatible con el servidor o tengo que agregar explícitamente esta línea de código:

 System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12; 

¿Hay alguna manera de cambiar este valor predeterminado, además de un cambio de código?

Por último, ¿ .NET 4.0 solo admite hasta TLS 1.0 ? es decir, tengo que actualizar los proyectos del cliente a 4.5 para que sean compatibles con TLS 1.2 .

Mi motivación es eliminar la compatibilidad con SSLv3 en el lado del cliente, incluso si el servidor lo admite (ya tengo un script de powershell para deshabilitar esto en el registro de la máquina) y para admitir el protocolo TLS más alto que admite el servidor.

Actualización: mirando la clase ServicePointManager en .NET 4.0 no veo valores enumerados para TLS 1.0 y 1.1 . En .NET 4.0/4.5 , el valor predeterminado es SecurityProtocolType.Tls|SecurityProtocolType.Ssl3 . Esperemos que este valor predeterminado no se rompa al deshabilitar SSLv3 en el registro.

Sin embargo, he decidido que tengo que actualizar todas las aplicaciones a .NET 4.5 y agregar explícitamente SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12; SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12; de todos modos a todos los códigos de arranque de todas las aplicaciones.

Esto hará que las solicitudes salientes a varias aplicaciones y servicios no se degraden a SSLv3 y debe seleccionar el nivel más alto de TLS .

¿Este enfoque suena razonable o excesivo? Tengo muchas aplicaciones para actualizar, y deseo probarlas en el futuro ya que incluso algunos proveedores podrían desaprobar el TLS 1.0 en un futuro cercano.

Como cliente que realiza solicitudes de salida a API, ¿la deshabilitación de SSL3 en el registro tiene un efecto en .NET Framework? Veo por defecto que TLS 1.1 y 1.2 no están habilitados, ¿tenemos que habilitarlo a través del registro? RE http://support.microsoft.com/kb/245030 .

Después de un poco de investigación, creo que la configuración del registro no tendrá ningún efecto ya que se aplican a IIS (subclave del servidor) y navegadores (subclave del cliente).

Lamento que esta publicación se haya convertido en varias preguntas, seguida de respuestas “tal vez”.

Algunos de los que han dejado comentarios han notado que establecer System.Net.ServicePointManager.SecurityProtocol en valores específicos significa que su aplicación no podrá aprovechar futuras versiones de TLS que pueden convertirse en los valores predeterminados en futuras actualizaciones de .NET. En lugar de especificar una lista fija de protocolos, puede activar o desactivar los protocolos que conoce y le preocupan, dejando los demás como están.

Para activar TLS 1.1 y 1.2 sin afectar otros protocolos:

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

Observe el uso de |= para activar estos indicadores sin desactivar otros.

Para desactivar SSL3 sin afectar otros protocolos:

 System.Net.ServicePointManager.SecurityProtocol &= ~SecurityProtocolType.Ssl3; 

El System.Net.ServicePointManager.SecurityProtocol predeterminado en .NET 4.0/4.5 es SecurityProtocolType.Tls|SecurityProtocolType.Ssl3 .

.NET 4.0 admite hasta TLS 1.0 mientras que .NET 4.5 admite hasta TLS 1.2

Sin embargo, una aplicación dirigida a .NET 4.0 aún puede admitir hasta TLS 1.2 si .NET 4.5 está instalado en el mismo entorno. .NET 4.5 instala encima de .NET 4.0 , reemplazando a System.dll .

Lo he verificado al observar el protocolo de seguridad correcto establecido en el tráfico con fiddler4 y al configurar manualmente los valores enumerados en un proyecto .NET 4.0 :

 ServicePointManager.SecurityProtocol = (SecurityProtocolType)192 | (SecurityProtocolType)768 | (SecurityProtocolType)3072; 

Referencia:

 namespace System.Net { [System.Flags] public enum SecurityProtocolType { Ssl3 = 48, Tls = 192, Tls11 = 768, Tls12 = 3072, } } 

Si intenta hackear un entorno con SOLO .NET 4.0 instalado, obtendrá la excepción:

Excepción no controlada: System.NotSupportedException: el protocolo de seguridad solicitado no es compatible. en System.Net.ServicePointManager.set_SecurityProtocol (SecurityProtocolType v alue)

Sin embargo, no recomendaría este “truco” ya que un parche futuro, etc. puede romperlo. *

Por lo tanto, he decidido que la mejor ruta para eliminar soporte para SSLv3 es:

  1. Actualice todas las aplicaciones a .NET 4.5
  2. Agregue lo siguiente al código de boostrapping para anular la prueba predeterminada y futura:

    System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

* Alguien me corrige si este truco está mal, pero las pruebas iniciales veo que funciona

Puede anular el comportamiento predeterminado en el siguiente registro:

 Key : HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319 Value: SchUseStrongCrypto Data : 1 

Para más detalles, consulte la implementación de ServicePointManager .

Crea un archivo de texto con una extensión .reg y los siguientes contenidos:

 Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319] "SchUseStrongCrypto"=dword:00000001 [HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319] "SchUseStrongCrypto"=dword:00000001 

O descárguelo de la siguiente fuente:

https://tls1test.salesforce.com/s/NET40-Enable-TLS-1_2.reg

Haga doble clic para instalar …

He descubierto que cuando especifico solo TLS 1.2, todavía negociará por debajo de 1.1. System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

Lo he especificado en el método de inicio Global.asax para mi aplicación web .net 4.5.

El mecanismo de cambio de registro funcionó para mí después de una lucha. En realidad, mi aplicación se estaba ejecutando como 32 bits. Entonces tuve que cambiar el valor debajo de la ruta.

 HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft.NETFramework\v4.0.30319 

El tipo de valor debe ser DWORD y el valor por encima de 0. Mejor uso 1. Configuración del registro para obtener el uso de la aplicación .Net 4.0 TLS 1.2 siempre que .Net 4.5 esté instalado en la máquina.

Obtuve el problema cuando mi cliente actualizó TLS de 1.0 a 1.2. Mi aplicación usa .NET Framework 3.5 y se ejecuta en el servidor. Así que lo arreglé de esta manera:

  1. Arreglar el progtwig

Antes de llamar a HttpWebRequest.GetResponse () agregue este comando:

 ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolTypeExtensions.Tls11 | SecurityProtocolTypeExtensions.Tls12; 

Extensiones 2 DLL agregando 2 nuevas clases: System.Net y System.Security.Authentication

  namespace System.Net { using System.Security.Authentication; public static class SecurityProtocolTypeExtensions { public const SecurityProtocolType Tls12 = (SecurityProtocolType)SslProtocolsExtensions.Tls12; public const SecurityProtocolType Tls11 = (SecurityProtocolType)SslProtocolsExtensions.Tls11; public const SecurityProtocolType SystemDefault = (SecurityProtocolType)0; } } namespace System.Security.Authentication { public static class SslProtocolsExtensions { public const SslProtocols Tls12 = (SslProtocols)0x00000C00; public const SslProtocols Tls11 = (SslProtocols)0x00000300; } } 
  1. Actualice el lote de Microsoft

Descargar lote:

  • Para Windows 2008 R2: windows6.1-kb3154518-x64.msu
  • Para Windows 2012 R2: windows8.1-kb3154520-x64.msu

Para el lote de descarga y más detalles, puede verlo aquí:

https://support.microsoft.com/en-us/help/3154518/support-for-tls-system-default-versions-included-in-the-.net-framework-3.5.1-on-windows-7 -sp1-y-server-2008-r2-sp1

Me estoy ejecutando bajo .NET 4.5.2, y no estaba contento con ninguna de estas respuestas. Como hablo con un sistema que admite TLS 1.2, y dado que SSL3, TLS 1.0 y TLS 1.1 están todos rotos y no son seguros para su uso, no deseo habilitar estos protocolos. En .NET 4.5.2, los protocolos SSL3 y TLS 1.0 están habilitados por defecto, lo que puedo ver en el código al inspeccionar ServicePointManager.SecurityProtocol . Bajo .NET 4.7, existe el nuevo modo de protocolo SystemDefault que entrega explícitamente la selección del protocolo al sistema operativo, donde creo que confiar en el registro u otras configuraciones de sistema sería apropiado. Eso no parece ser compatible con .NET 4.5.2 sin embargo. En aras de escribir código compatible con Forwards, eso seguirá tomando las decisiones correctas incluso cuando TLS 1.2 se rompa inevitablemente en el futuro, o cuando actualizo a .NET 4.7+ y le entregue más responsabilidad para seleccionar un protocolo apropiado para el SO , Adopté el siguiente código:

 SecurityProtocolType securityProtocols = ServicePointManager.SecurityProtocol; if (securityProtocols.HasFlag(SecurityProtocolType.Ssl3) || securityProtocols.HasFlag(SecurityProtocolType.Tls) || securityProtocols.HasFlag(SecurityProtocolType.Tls11)) { securityProtocols &= ~(SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11); if (securityProtocols == 0) { securityProtocols |= SecurityProtocolType.Tls12; } ServicePointManager.SecurityProtocol = securityProtocols; } 

Este código detectará cuándo está habilitado un protocolo inseguro conocido, y en este caso, eliminaremos estos protocolos inseguros. Si no quedan otros protocolos explícitos, forzaremos habilitar TLS 1.2 como el único protocolo seguro compatible con .NET en este momento. Este código es compatible con versiones anteriores, ya que tendrá en cuenta los nuevos tipos de protocolo que no sabe si se agregarán en el futuro, y también funcionará bien con el nuevo estado SystemDefault en .NET 4.7, lo que significa que no tendré que vuelva a visitar este código en el futuro. Recomiendo encarecidamente adoptar un enfoque como este, en lugar de forzar la encoding incondicional de cualquier protocolo de seguridad en particular, de lo contrario tendrá que volver a comstackr y reemplazar su cliente con una nueva versión para actualizar a un nuevo protocolo de seguridad cuando TLS 1.2 se rompe inevitablemente, o es más probable que tenga que dejar los protocolos inseguros existentes encendidos durante años en su servidor, haciendo que su organización sea un objective para los ataques.

El siguiente código:

  • imprimir protocolos habilitados
  • imprimir protocolos disponibles
  • habilitar TLS1.2 si la plataforma lo admite y si no está habilitado para comenzar con
  • deshabilitar SSL3 si está habilitado
  • imprimir resultado final

Otros protocolos no se verán afectados. Esto hace que esto sea compatible con futuros protocolos (Tls1.3, etc.).

Código

  Console.WriteLine("Runtime: " + System.Diagnostics.FileVersionInfo.GetVersionInfo(typeof(int).Assembly.Location).ProductVersion); Console.WriteLine("Enabled protocols: " + ServicePointManager.SecurityProtocol); Console.WriteLine("Available protocols: "); Boolean platformSupportsTls12 = false; foreach (SecurityProtocolType protocol in Enum.GetValues(typeof(SecurityProtocolType))) { Console.WriteLine(protocol.GetHashCode()); if (protocol.GetHashCode() == 3072){ platformSupportsTls12 = true; } } Console.WriteLine("Is Tls12 enabled: " + ServicePointManager.SecurityProtocol.HasFlag((SecurityProtocolType)3072)); // enable Tls12, if possible if (!ServicePointManager.SecurityProtocol.HasFlag((SecurityProtocolType)3072){ if (platformSupportsTls12){ Console.WriteLine("Platform supports Tls12, but it is not enabled. Enabling it now."); ServicePointManager.SecurityProtocol |= (SecurityProtocolType)3072; } else { Console.WriteLine("Platform does not supports Tls12."); } } if (ServicePointManager.SecurityProtocol.HasFlag(SecurityProtocolType.Ssl3)) { Console.WriteLine("Ssl3SSL3 is enabled. Disabling it now."); // disable SSL3. Has no negative impact if SSL3 is already disabled. The enclosing "if" if just for illustration. System.Net.ServicePointManager.SecurityProtocol &= ~SecurityProtocolType.Ssl3; } Console.WriteLine("Enabled protocols: " + ServicePointManager.SecurityProtocol); 

Salida

48 – SSL3, 192 – TLS1, 768 – TLS1.1, 3072 – TLS1.2

 Runtime: 4.7.2114.0 Enabled protocols: Ssl3, Tls Available protocols: 0 48 192 768 3072 Is Tls12 enabled: False Platform supports Tls12, but it is not enabled. Enabling it now. Ssl3 is enabled. Disabling it now. Enabled protocols: Tls, Tls12 

Para completar, aquí hay una secuencia de comandos de Powershell que establece las claves de registro mencionadas anteriormente:

 new-itemproperty -path "HKLM:\SOFTWARE\Microsoft\.NETFramework\v4.0.30319" -name "SchUseStrongCrypto" -Value 1 -PropertyType "DWord"; new-itemproperty -path "HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319" -name "SchUseStrongCrypto" -Value 1 -PropertyType "DWord" 

La MEJOR solución a este problema parece ser la actualización a al menos .NET 4.6 o posterior, que automáticamente elegirá protocolos potentes así como cifrados fuertes.

Si no puede actualizar a .NET 4.6, el consejo de configuración

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

Y usando la configuración de registro:

HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft.NETFramework \ v4.0.30319 – SchUseStrongCrypto = DWORD de 1 HKEY_LOCAL_MACHINE \ SOFTWARE \ Wow6432Node \ Microsoft.NETFramework \ v4.0.30319 – SchUseStrongCrypto = DWORD de 1

Resulta en el uso de algo que no sea TLS 1.0 y un cifrado fuerte.

En mi prueba, solo la configuración en el Wow6432Node hizo alguna diferencia, a pesar de que mi aplicación de prueba fue creada para Cualquier CPU.

Una alternativa a la encoding rígida de ServicePointManager.SecurityProtocol o la clave SchUseStrongCrypto explícita como se mencionó anteriormente:
Puede decirle a .NET que use la configuración predeterminada de SCHANNEL con la clave SystemDefaultTlsVersions,
p.ej:

 [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319] "SystemDefaultTlsVersions"=dword:00000001 [HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319] "SystemDefaultTlsVersions"=dword:00000001 

Para la clave: HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft.NETFramework \ v4.0.30319 Valor: SchUseStrongCrypto

Debe establecer el valor en 1.