SecurityProtocol par défaut dans .NET 4.5

Quel est le protocole de sécurité par défaut pour communiquer avec les serveurs prenant en charge TLS 1.2 ? Will .NET par défaut, choisissez le protocole de sécurité le plus élevé supporté côté serveur ou dois-je append explicitement cette ligne de code:

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

Y a-t-il un moyen de changer cette valeur par défaut, en plus d’un changement de code?

Enfin, .NET 4.0 il en charge uniquement TLS 1.0 ? c’est-à-dire que je dois mettre à niveau les projets clients à 4.5 pour prendre en charge TLS 1.2 .

Ma motivation est de supprimer la prise en charge de SSLv3 du côté client même si le serveur le prend en charge (j’ai déjà un script powershell pour le désactiver dans le registre des machines) et pour prendre en charge le protocole TLS le plus élevé pris en charge par le serveur.

Mise à jour: En regardant la classe ServicePointManager dans .NET 4.0 je ne vois aucune valeur énumérée pour TLS 1.0 et 1.1 . Dans les deux .NET 4.0/4.5 , la valeur par défaut est SecurityProtocolType.Tls|SecurityProtocolType.Ssl3 . Espérons que cette valeur par défaut ne sera pas interrompue en désactivant SSLv3 dans le registre.

Cependant, j’ai décidé de mettre à niveau toutes les applications vers .NET 4.5 et d’append explicitement SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12; SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12; de toute façon à tous les codes d’amorçage de toutes les applications.

Cela fera en sorte que les demandes sortantes adressées à divers apis et services ne seront pas rétrogradées vers SSLv3 et devront sélectionner le niveau le plus élevé de TLS .

Est-ce que cette approche semble raisonnable ou exagérée? J’ai de nombreuses applications à mettre à jour, et je veux les tester à l’avenir, car j’entends que même TLS 1.0 pourrait être déprécié dans un avenir proche par certains fournisseurs.

En tant que client effectuant des requêtes sortantes vers des API, la désactivation de SSL3 dans le registre a-t-elle même un effet sur le framework .NET? Je vois par défaut, TLS 1.1 et 1.2 ne sont pas activés, devons-nous l’activer via le registre? RE http://support.microsoft.com/kb/245030 .

Après quelques recherches, je pense que les parameters du registre n’auront aucun effet car ils s’appliquent à IIS (sous-clé du serveur) et aux navigateurs (sous-clé du client).

Désolé, cet article s’est transformé en questions multiples, suivies de réponses “peut-être”.

Certains de ces commentaires ont indiqué que la définition de System.Net.ServicePointManager.SecurityProtocol sur des valeurs spécifiques signifie que votre application ne pourra pas tirer parti des futures versions de TLS susceptibles de devenir les valeurs par défaut des futures mises à jour de .NET. Au lieu de spécifier une liste fixe de protocoles, vous pouvez activer ou désactiver les protocoles que vous connaissez et dont vous vous souciez, en laissant les autres tels quels.

Pour activer TLS 1.1 et 1.2 sans affecter les autres protocoles:

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

Notez l’utilisation de |= pour activer ces indicateurs sans désactiver les autres.

Pour désactiver SSL3 sans affecter les autres protocoles:

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

La valeur par défaut System.Net.ServicePointManager.SecurityProtocol dans .NET 4.0/4.5 est SecurityProtocolType.Tls|SecurityProtocolType.Ssl3 .

.NET 4.0 prend en charge jusqu’à TLS 1.0 tandis que .NET 4.5 prend en charge jusqu’à TLS 1.2

Toutefois, une application ciblant .NET 4.0 peut toujours prendre en charge TLS 1.2 si .NET 4.5 est installé dans le même environnement. .NET 4.5 s’installe sur .NET 4.0 , en remplacement de System.dll .

Je l’ai vérifié en observant le protocole de sécurité correct défini dans le trafic avec fiddler4 et en définissant manuellement les valeurs énumérées dans un projet .NET 4.0 :

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

Référence:

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

Si vous tentez le hack sur un environnement avec UNIQUEMENT .NET 4.0 installé, vous obtiendrez l’exception:

Exception non gérée: System.NotSupportedException: le protocole de sécurité demandé n’est pas pris en charge. at System.Net.ServicePointManager.set_SecurityProtocol (SecurityProtocolType v alue)

Cependant, je ne recommanderais pas ce “hack” car un futur patch, etc. peut le casser. *

Par conséquent, j’ai décidé que la meilleure voie pour supprimer la prise en charge de SSLv3 consiste à:

  1. Mettre à niveau toutes les applications vers .NET 4.5
  2. Ajoutez les éléments suivants au code de mise à niveau pour remplacer la preuve par défaut et la preuve future:

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

* Quelqu’un me corrige si ce piratage est faux, mais les premiers tests que je vois fonctionnent

Vous pouvez remplacer le comportement par défaut dans le registre suivant:

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

Pour plus de détails, consultez l’ implémentation de ServicePointManager .

Créez un fichier texte avec une extension .reg et le contenu suivant:

 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 

Ou téléchargez-le à partir de la source suivante:

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

Double-cliquez pour installer …

J’ai trouvé que lorsque je spécifie uniquement TLS 1.2, il sera toujours négocié à 1.1. System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

Je l’ai spécifié dans la méthode de démarrage de Global.asax pour mon application Web .net 4.5.

Le mécanisme de changement de registre a fonctionné pour moi après une lutte. En fait, ma demande fonctionnait en 32 bits. J’ai donc dû modifier la valeur sous le chemin.

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

Le type de valeur doit être DWORD et la valeur supérieure à 0. Meilleure utilisation 1. Les paramètres du registre pour obtenir l'application .Net 4.0 utilisent TLS 1.2 à condition que .Net 4.5 soit installé sur la machine.

J’ai eu le problème lorsque mon client a mis à niveau TLS de 1.0 à 1.2. Mon application utilise .net framework 3.5 et s’exécute sur le serveur. Je l’ai donc corrigé de cette façon:

  1. Fixer le programme

Avant d’appeler HttpWebRequest.GetResponse () ajoutez cette commande:

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

Extensions 2 DLL en ajoutant 2 nouvelles classes: System.Net et 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. Mettre à jour le lot Microsoft

Télécharger le lot:

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

Pour télécharger le lot et plus de détails, vous pouvez voir ici:

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

Je cours sous .NET 4.5.2, et je n’étais satisfait d’aucune de ces réponses. Comme je parle à un système qui prend en charge TLS 1.2, et vu que SSL3, TLS 1.0 et TLS 1.1 sont tous endommagés et dangereux à utiliser, je ne veux pas activer ces protocoles. Sous .NET 4.5.2, les protocoles SSL3 et TLS 1.0 sont tous deux activés par défaut, ce que je peux voir dans le code en inspectant ServicePointManager.SecurityProtocol . Sous .NET 4.7, il y a le nouveau mode de protocole SystemDefault qui SystemDefault explicitement la sélection du protocole au système d’exploitation, où j’estime que le recours à des parameters de registre ou à d’autres parameters de configuration du système serait approprié. Cela ne semble cependant pas être supporté sous .NET 4.5.2. Dans l’intérêt de l’écriture de code compatible avec la suite, cela continuera à prendre les bonnes décisions, même lorsque TLS 1.2 sera inévitablement cassé à l’avenir, ou lorsque je passerai à .NET 4.7+ et confierai plus de responsabilités pour sélectionner un protocole approprié au système d’exploitation. , J’ai adopté le code suivant:

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

Ce code détectera lorsqu’un protocole non sécurisé connu est activé et, dans ce cas, nous supprimerons ces protocoles non sécurisés. S’il ne rest aucun autre protocole explicite, nous activerons ensuite TLS 1.2, en tant que seul protocole sécurisé connu pris en charge par .NET à ce stade. Ce code est compatible avec les SystemDefault , car il prendra en compte les nouveaux types de protocoles dont il ne sait pas qu’il sera ajouté à l’avenir, et il fonctionnera également avec le nouvel état SystemDefault de .NET 4.7, ce qui signifie revoir ce code à l’avenir. Je recommande fortement d’adopter une approche comme celle-ci, plutôt que de coder de manière inconditionnelle tout état de protocole de sécurité particulier, sinon vous devrez recomstackr et remplacer votre client par une nouvelle version afin de passer à un nouveau protocole de sécurité lorsque TLS 1.2 est inévitablement cassé, ou plus probablement vous devrez laisser les protocoles non sécurisés activés pendant des années sur votre serveur, faisant de votre organisation une cible pour les attaques.

Le code suivant va:

  • imprimer les protocoles activés
  • imprimer les protocoles disponibles
  • activer TLS1.2 si la plate-forme le prend en charge et s’il n’est pas activé pour commencer
  • désactiver SSL3 s’il est activé
  • résultat final d’impression

Les autres protocoles ne seront pas affectés. Cela rend cela compatible avec les futurs protocoles (Tls1.3, etc.).

Code

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

Sortie

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 

Pour être complet, voici un script Powershell qui définit les clés de registre susmentionnées:

 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 MEILLEURE solution à ce problème semble être la mise à niveau vers au moins .NET 4.6 ou version ultérieure, qui choisira automatiquement des protocoles puissants ainsi que des codes de chiffrement puissants.

Si vous ne pouvez pas mettre à niveau vers .NET 4.6, les conseils de paramétrage

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

Et en utilisant les parameters du registre:

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

Cela a pour résultat d’utiliser autre chose que TLS 1.0 et un chiffrement fort.

Lors de mes tests, seul le paramètre dans Wow6432Node a fait la différence, même si mon application de test a été créée pour Any CPU.

Une alternative à la codage en dur ServicePointManager.SecurityProtocol ou à la clé explicite SchUseStrongCrypto comme mentionné ci-dessus:
Vous pouvez indiquer à .NET d’utiliser les parameters SCHANNEL par défaut avec la clé SystemDefaultTlsVersions,
par exemple:

 [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 

Pour la clé: HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft.NETFramework \ v4.0.30319 Valeur: SchUseStrongCrypto

Vous devez définir la valeur sur 1.