SecurityProtocol predeterminado en .NET 4.5

253

¿Cuál es el protocolo de seguridad predeterminado para comunicarse con servidores que admiten hasta TLS 1.2? Será .NETpor defecto, seleccione el protocolo de seguridad más alta soportada en el lado del servidor o tengo que añadir 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.0solo admite hasta TLS 1.0? es decir, tengo que actualizar los proyectos del cliente a 4.5 para admitirlos TLS 1.2.

Mi motivación es eliminar el soporte SSLv3del 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 admitir el protocolo TLS más alto que el servidor admite.

Actualización: Mirando la ServicePointManagerclase en .NET 4.0No veo valores enumerados para TLS 1.0y 1.1. En ambos .NET 4.0/4.5, el valor predeterminado es SecurityProtocolType.Tls|SecurityProtocolType.Ssl3. Esperemos que este valor predeterminado no se rompa deshabilitando SSLv3en el registro.

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

Esto hará que las solicitudes salientes a varias API y servicios no se degraden SSLv3y deben seleccionar el nivel más alto TLS.

¿Este enfoque suena razonable o excesivo? Tengo muchas aplicaciones para actualizar, y quiero probarlas en el futuro, ya que escuché que TLS 1.0algunos proveedores pueden dejar de usarlas en el futuro cercano.

Como cliente que realiza solicitudes de salida a las API, ¿la desactivación de SSL3 en el registro tiene algún efecto en el marco .NET? Veo por defecto, 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 de servidor) y navegadores (subclave de cliente).

Lo sentimos, esta publicación se convirtió en varias preguntas, seguidas de respuestas "quizás".

Luke Hutton
fuente
FYI: Últimas mejores prácticas en torno a TLS: docs.microsoft.com/en-us/dotnet/framework/network-programming/…
JohnLBevan
Para aquellos que quieran ver la mejor respuesta para esto, ¡clasifiquen por votos!
navule
1
Preguntas y respuestas relacionadas con SO: stackoverflow.com/questions/41618766/… Los lectores deben tener en cuenta que esta pregunta está caducando y que hay nuevas recomendaciones vigentes a partir de 2020.
No hay reembolsos ni devoluciones

Respuestas:

280

Algunos de los que dejan comentarios han notado que la configuración System.Net.ServicePointManager.SecurityProtocol 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 interesan, dejando los demás tal 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 estas banderas sin desactivar otras.

Para desactivar SSL3 sin afectar otros protocolos:

System.Net.ServicePointManager.SecurityProtocol &= ~SecurityProtocolType.Ssl3;
Scott
fuente
66
Esta es realmente la respuesta correcta. La respuesta aceptada garantizará que su aplicación siempre desactive las nuevas versiones de TLS a menos que regrese y actualice su código.
Connor
55
@Gertsen No, es un bit a bit o, por lo que solo activa los bits apropiados si están apagados. Si esos bits ya están activados, no se produce ningún cambio.
Scott
3
Y el equivalente de PowerShell de esto es [Net.ServicePointManager]::SecurityProtocol = ([Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls11 -bor [Net.SecurityProtocolType]::Tls12) Invoke-RestMethod se basa en las mismas bibliotecas subyacentes de .NET Framework.
Martin Hollingsworth
15
Como nadie habla de dónde colocar este código, lo puse con éxito en Application_Start de Global.asax.cs para mi aplicación ASP.NET MVC. Estaba buscando cómo enviar mis solicitudes SMTP a través de TLS1.2 y NO a través de TLS1.0. También agregué & = ~ SecurityProtocolType.Tls para desactivar TLS 1.0
Greg Veres
2
En VB, el equivalente esNet.ServicePointManager.SecurityProtocol = Net.ServicePointManager.SecurityProtocol OR Net.SecurityProtocolType.Tls12 OR Net.SecurityProtocolType.Tls12
codificado
188

El valor predeterminado System.Net.ServicePointManager.SecurityProtocolen ambos .NET 4.0/4.5es SecurityProtocolType.Tls|SecurityProtocolType.Ssl3.

.NET 4.0soporta hasta TLS 1.0mientras .NET 4.5soporta hastaTLS 1.2

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

He verificado esto observando el protocolo de seguridad correcto establecido en el tráfico fiddler4y configurando manualmente los valores enumerados en un .NET 4.0proyecto:

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.0instalado, 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., podría romperlo. *

Por lo tanto, he decidido que la mejor ruta para eliminar el soporte SSLv3es:

  1. Actualice todas las aplicaciones a .NET 4.5
  2. Agregue lo siguiente al código de reinicio para anular los valores predeterminados y futuros:

    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

Luke Hutton
fuente
66
Consulte imperialviolet.org/2014/12/08/poodleagain.html "Este parece ser un buen momento para reiterar que todo menos que TLS 1.2 con un conjunto de cifrado AEAD está roto criptográficamente".
Neil
3
@Mathew, al ver el código fuente de ServicePointManager.cssee referencesource.microsoft.com/#System/net/System/Net/…
Luke Hutton el
12
Sigo viendo que las personas reclaman los .NET 4.5valores predeterminados de Tls12, pero como ha dicho aquí, no lo hace. Te da la opción de usarloSecurityProtocol
Don Cheadle
17
No rechazaré esta respuesta, ya que proporciona mucha información útil, pero la implementación de una versión de protocolo codificada no es una buena idea, ya que restringirá el uso de la mejor encriptación disponible y puede ocasionar problemas de seguridad en el futuro. Los cambios en el registro para cambiar el comportamiento predeterminado de .Net para admitir protocolos modernos es muy preferible. (Sin embargo, vale la pena señalar que el cambio en el registro también deshabilita SSL v3.)
AJ Henderson
66
En FW 4.6 y 4.7, el valor predeterminado es ahora SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12según support.microsoft.com/en-us/help/3069494/…
Ian Kemp
68

Puede anular el comportamiento predeterminado en el siguiente registro:

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

y

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

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

Jiri Mares
fuente
Gracias, no sabía sobre esto. Lo probaré Creé
Luke Hutton
66
Cambiar el registro no parece una buena solución. Si la aplicación desea admitir TLS1, la aplicación debe tener cuidado al respecto. No es el entorno de ejecución. De lo contrario, podría dañar otras aplicaciones o hacer un infierno al implementar y actualizar su aplicación.
Mikhail G
13
@MikhailG todo lo contrario. El cambio de registro es el método preferible. SChannel proporciona una abstracción de la negociación subyacente y desea que su aplicación utilice el nivel de seguridad más alto admitido. Limitarlo artificialmente en el software resulta en problemas futuros cuando se lanzan nuevos protocolos y su software no puede usarlos. Sería bueno si hubiera una opción para decir usar solo mejor que un protocolo dado en el software, pero no hay una opción para eso sin también evitar que las futuras versiones funcionen. Aunque deshabilitó SSL v3 con ese cambio ..
AJ Henderson
13
Línea de comando: reg add HKLM\SOFTWARE\Microsoft\.NETFramework\v4.0.30319 /v SchUseStrongCrypto /t REG_DWORD /d 1 /reg:64(y / o /reg:32)
Kevin Smyth
77
@MikhailG: configurar el registro no impide que las aplicaciones admitan protocolos más antiguos. Solo cambia los valores predeterminados (que incluyen tls 1.0 a partir de ahora). Además, el comportamiento predeterminado en .Net 4.6+ es usar criptografía fuerte; en ese caso, esta entrada del registro solo sería útil como un medio para deshabilitar el cifrado fuerte.
Brian
51

Cree un archivo de texto con una .regextensión 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 ...

dana
fuente
3
El enlace que proporcionó parece tener problemas con el certificado SSL.
NathanAldenSr
Incluso cuando agrego estas claves de registro, todavía tengo ese problema. Alguna idea ?
Samidjo
@Samidjo - ¿Qué versión .NET estás usando? La respuesta de Luke entra en muchos más detalles que la mía, pero parece que necesita al menos tener instalado .NET 4.5. Además, si acaba de realizar el cambio, es posible que deba reciclar el grupo de aplicaciones. Estos son una especie de conjeturas, por lo que sin más detalles podría ayudar mucho más :)
dana
2
Un parche aplicado recientemente support.microsoft.com/en-us/help/4019114/… a un servidor provocó que nuestra aplicación .net 4.5.2 fallara en las solicitudes REST de https. Estas claves resolvieron nuestro problema.
Kleinux
21

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

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

Jim
fuente
2
¿Cuál es el protocolo de seguridad compatible en el servidor? Creo que ese es el factor aquí también y puede ser 1.1 es el último en el servidor. www.passionatecoder.ca
Ehsan
14
Votó porque esta es la única respuesta que dice DÓNDE colocar la línea de código que es la solución.
jgerman
1
El cliente (p. Ej., Su cliente web C #) y el servidor (servidor API al que llama) negociarán el uso del protocolo más alto que ambos admitan. Entonces, si su cliente admite TLS 1.2, pero el servidor solo TLS 1.1: el Cliente usará TLS 1.1 (a menos que ELIMINE TLS 1.1 de su cliente, en cuyo caso es posible que no encuentren un protocolo compatible mutuamente y el Cliente cometerá un error)
Don Cheadle
Tuve que agregar usando System.Net en global.asax.cs
Patrick
16

El siguiente código:

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

Constantes:

  • 48 es SSL3
  • 192 es TLS1
  • 768 es TLS1.1
  • 3072 es TLS1.2

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

Código

// print initial status
    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.");
        }
    }

// disable ssl3
   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

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
gerasoras
fuente
14

Tuve 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 programa

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. Actualizar 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 ver 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-and-server-2008-r2-sp1

Hieu
fuente
1
¿Es posible cambiar el SecurityProtocol sin cambiar el código fuente? como un machine.config o app.config.
ahankendi
1
Guau. Ese es el premio vudú del año ... material ... justo ahí. ¡Oscuras los suburbios!
granadaCoder
14

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

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

El tipo de valor debe ser DWORD y un valor superior a 0. Mejor uso 1.La configuración del registro para obtener la aplicación .Net 4.0 usa TLS 1.2 siempre que .Net 4.5 esté instalado en la máquina.

Joy George Kunjikkuru
fuente
No es exacto Para .NET 4.5.2, esto debe establecerse en 1 (o superior); pero para .NET 4.6, es suficiente no estar configurado en 0 (es decir, puede estar desarmado).
Jirka Hanika
Oh, no probé en .Net 4.6. Mis hallazgos están allí en el blogpost joymonscode.blogspot.com/2015/08/…
Joy George Kunjikkuru
La clave de registro que menciona debe leer "Wow6432Node". Omitió la parte "Nodo" por alguna razón. Traté de editar su respuesta, pero mi cambio fue de solo 4 letras, por lo que no me lo permitió. : \
Jeffrey LeCours
Tuve que rebotar IIS para tener esta configuración activa por sí misma como predeterminada.
Jeff Mitchell
10

Estoy ejecutando bajo .NET 4.5.2, y no estaba contento con ninguna de estas respuestas. Como estoy hablando con un sistema que admite TLS 1.2, y dado que SSL3, TLS 1.0 y TLS 1.1 están rotos e inseguros para su uso, no quiero habilitar estos protocolos. Bajo .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, está el nuevoSystemDefaultmodo de protocolo que entrega explícitamente la selección del protocolo al sistema operativo, donde creo que sería apropiado confiar en el registro u otras configuraciones del sistema. Sin embargo, eso no parece ser compatible con .NET 4.5.2. En aras de escribir código compatible con reenvío, eso seguirá tomando las decisiones correctas incluso cuando TLS 1.2 se rompa inevitablemente en el futuro, o cuando actualice a .NET 4.7+ y entregue más responsabilidad para seleccionar un protocolo apropiado para el sistema operativo , 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á cuando se habilite un protocolo inseguro conocido y, en este caso, eliminaremos estos protocolos inseguros. Si no quedan otros protocolos explícitos, forzaremos la habilitación de TLS 1.2, como el único protocolo seguro conocido compatible con .NET en este momento. Este código es compatible con versiones posteriores, ya que tendrá en cuenta los nuevos tipos de protocolos que no conoce sobre su incorporación en el futuro, y también jugará bien con el nuevoSystemDefaultestado en .NET 4.7, lo que significa que no tendré que volver a visitar este código en el futuro. Recomiendo encarecidamente adoptar un enfoque como este, en lugar de codificar de manera incondicional cualquier estado de protocolo de seguridad en particular, de lo contrario, tendrá que volver a compilar y reemplazar su cliente con una nueva versión para actualizar a un nuevo protocolo de seguridad cuando TLS 1.2 está inevitablemente roto, o es más probable que tenga que dejar los protocolos inseguros existentes activados durante años en su servidor, haciendo de su organización un objetivo para los ataques.

Roger Sanders
fuente
1
Esta respuesta parece la más pensada, sin embargo, a menos que me falte algo, no estoy seguro de que sea compatible con versiones posteriores cuando TLS 1.2 se rompa inevitablemente. Por lo que estoy viendo en mi aplicación .NET 4.7.2, el SecurityProtocolType.SystemDefaultindicador se evalúa 0, por lo que verificar if (securityProtocols == 0)con el indicador de inclusión bit a bit o TLS 1.2 siempre incluirá TLS 1.2, incluso después de que se "rompa", ¿verdad? No hay disparos bruscos aquí. Realmente estoy tratando de encontrar el mejor camino a seguir.
Griswald_911
He modificado el código para incluir este y parece que trabajar y ser compatibles con las versiones: if (!Enum.IsDefined(typeof(SecurityProtocolType), 0) && securityProtocols == 0) { securityProtocols |= SecurityProtocolType.Tls12; }.
Griswald_911
@ Griswald_911, tengo un código similar en mi aplicación de consola 4.7.2, y encontré que esta línea securityProtocols |= SecurityProtocolType.Tls12;(sin bloqueo) no mantiene SystemDefault, el securityProtocols solo tiene TLS2 después. Entonces, ¿quiere decir que cuando el valor es SystemDefault, no se debe actualizar ningún valor? Con respecto a la compatibilidad directa, ¿está asumiendo que el sistema operativo se encargaría de habilitar un protocolo más nuevo como TLS 1.3?
Yang
@Yang - Correcto. La línea securityProtocols |= SecurityProtocolType.Tls12;' will add TLS 1.2, but because the SecurityProtocolType` enum tiene un [Flags]atributo, y el valor de enumeración SystemDefault es 0, el valor SystemDefault se eliminará, incluso si se estableció previamente. El resultado final es que puede establecerlo SevicePointManager.SecurityProtocol en 0 o en cualquier combinación de los otros valores de enumeración. Si lo configura en SystemDefault, básicamente está optando por no especificar el protocolo usted mismo y dejar que el SO decida.
Griswald_911
1
@Yang: el punto es que, después de establecer el valor en SystemDefault, su aplicación debe usar lo que especifique el sistema operativo, que es TLS 1.2 en las últimas versiones de Windows 10. La idea es que, en el futuro, cuando TLS 1.3 se convierta estándar, no debería tener que modificar su aplicación para heredar esa funcionalidad. Ver la documentación aquí , donde SystemDefault "permite al sistema operativo elegir el mejor protocolo para usar y bloquear los protocolos que no son seguros".
Griswald_911
6

Microsoft publicó recientemente las mejores prácticas en torno a esto. https://docs.microsoft.com/en-us/dotnet/framework/network-programming/tls

Resumen

Diríjase a .Net Framework 4.7, elimine cualquier código que configure SecurityProtocol, por lo que el sistema operativo se asegurará de que use la solución más segura.

NB: También deberá asegurarse de que la última versión de TLS sea compatible y esté habilitada en su sistema operativo.

OS                          TLS 1.2 support

Windows 10                  \_ Supported, and enabled by default.
Windows Server 2016         /   
Windows 8.1                 \_ Supported, and enabled by default.
Windows Server 2012 R2      /
Windows 8.0                 \_ Supported, and enabled by default.
Windows Server 2012         /
Windows 7 SP1               \_ Supported, but not enabled by default*.
Windows Server 2008 R2 SP1  /
Windows Server 2008         -  Support for TLS 1.2 and TLS 1.1 requires an update. See Update to add support for TLS 1.1 and TLS 1.2 in Windows Server 2008 SP2.
Windows Vista               -  Not supported.

* To enable TLS1.2 via the registry see https://docs.microsoft.com/en-us/windows-server/security/tls/tls-registry-settings#tls-12 

    Path: HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS1.2\Server

        Property: Enabled
        Type: REG_DWORD
        Value: 1

        Property: DisabledByDefault 
        Type: REG_DWORD
        Value: 0

    Path: HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS1.2\Client

        Property: Enabled
        Type: REG_DWORD
        Value: 1

        Property: DisabledByDefault 
        Type: REG_DWORD
        Value: 0

Para obtener más información y marcos anteriores, consulte el enlace de MS.

JohnLBevan
fuente
3
El problema es que tls 1.1 y tls 1.2 no funcionarán en Windows 7 y Server 2008 si sigue las pautas (manteniendo SecurityProtocolType.SystemDefault) porque no están "habilitadas" (lo que sea que eso signifique) en estos sistemas operativos sin un cambio de registro. Esto hace que SystemDefault en la práctica se rompa por diseño. Microsoft realmente estropeó este.
osexpert
Buena, gracias @osexpert, buena captura. Modifiqué la respuesta para incluir información sobre los sistemas operativos compatibles, por lo que no hay sorpresas para las personas que ejecutan sistemas operativos más antiguos en los que simplemente apuntar a 4.7 no es suficiente.
JohnLBevan
1
NB: También hay una KB para habilitar los protocolos más nuevos en algunos sistemas operativos: support.microsoft.com/en-my/help/3140245/…
JohnLBevan
1
Si la configuración del registro no es una opción, creo que esta es la mejor solución para .NET 4.7+: if (System.Environment.OSVersion.Version < new Version(6, 2) /* Windows 8 */) ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12; else ServicePointManager.SecurityProtocol = SecurityProtocolType.SystemDefault;
osexpert
5

Para completar, aquí hay un script 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"
qbik
fuente
2

Una alternativa a la codificación rígida ServicePointManager.SecurityProtocolo la clave SchUseStrongCrypto explícita como se mencionó anteriormente:
puede indicarle a .NET que use la configuración predeterminada de SCHANNEL con la clave SystemDefaultTlsVersions,
por ejemplo:

[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
Alfredo
fuente
2

La MEJOR solución a este problema parece ser actualizar al menos a .NET 4.6 o posterior, que elegirá automáticamente protocolos fuertes y 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 del 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 of DWORD of 1WORD of DWORD of DWORD of DWORD of 1

Resultados en el uso de algo diferente a TLS 1.0 y un cifrado fuerte.

En mis pruebas, solo la configuración en el Wow6432Node hizo alguna diferencia, a pesar de que mi aplicación de prueba se creó para Any CPU.

GWC
fuente
Aclaración: solo necesita establecer SevicePointManager.SecurityProtocol O establecer la configuración del registro. No hay necesidad de hacer ambas cosas. Para mi aplicación, opté por configurar ServicePointManager.SecurityProtocol. Mi razonamiento es que configurar el registro afecta a toda la máquina, y no quería que la aplicación de otra persona se rompiera porque dependía de TLS 1.0.
GWC
1

De acuerdo con las mejores prácticas de Seguridad de la capa de transporte (TLS) con .NET Framework : para garantizar que las aplicaciones de .NET Framework permanezcan seguras, la versión de TLS no debe estar codificada. En su lugar, configure las claves de registro: SystemDefaultTlsVersions y SchUseStrongCrypto :

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v2.0.50727]
"SystemDefaultTlsVersions"=dword:00000001
"SchUseStrongCrypto"=dword:00000001

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

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v2.0.50727]
"SystemDefaultTlsVersions"=dword:00000001
"SchUseStrongCrypto"=dword:00000001

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319]
"SystemDefaultTlsVersions"=dword:00000001
"SchUseStrongCrypto"=dword:00000001
Benjamin Freitag
fuente
0

Si puede usar .NET 4.7.1 o posterior, usará TLS 1.2 como el protocolo mínimo basado en las capacidades del sistema operativo. Por recomendación de Microsoft:

To ensure .NET Framework applications remain secure, the TLS version should not be hardcoded. .NET Framework applications should use the TLS version the operating system (OS) supports.
Yanivhs
fuente
-2

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

Debe establecer el valor en 1.

kgw
fuente
55
Creo que te están rechazando porque es la misma respuesta que ofreció @Jira Mares, pero con menos detalles
Stuart Siegler