Protocole de sécurité par défaut dans .NET 4.5

254

Quel est le protocole de sécurité par défaut pour communiquer avec les serveurs qui prennent en charge jusqu'à TLS 1.2? Est-ce que .NETpar défaut, choisir le protocole de sécurité le plus élevé pris en charge sur le côté serveur ou dois - je ajouter explicitement cette ligne de code:

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

Existe-t-il un moyen de modifier cette valeur par défaut, en plus d'un changement de code?

Enfin, ne prend en .NET 4.0charge que jusqu'à TLS 1.0? c'est-à-dire que je dois mettre à niveau les projets clients vers 4.5 pour les soutenirTLS 1.2 .

Ma motivation est de supprimer le support pour SSLv3 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 de la machine) et de prendre en charge le protocole TLS le plus élevé pris en charge par le serveur.

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

Cependant, j'ai décidé de mettre à niveau toutes les applications vers .NET 4.5et d'ajouter de SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;toute façon explicitement à tout le code d'amorçage de toutes les applications.

Cela fera des demandes sortantes vers divers API et services pour ne pas rétrograder SSLv3et devrait sélectionner le niveau le plus élevé de TLS.

Cette approche semble-t-elle raisonnable ou excessive? J'ai de nombreuses applications à mettre à jour, et je veux les pérenniser car j'entends même qu'elles TLS 1.0pourraient être dépréciées dans un proche avenir 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 dans 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 un peu d'investigation, je pense que les paramètres de registre n'auront aucun effet car ils s'appliquent à IIS (sous-clé serveur) et aux navigateurs (sous-clé client).

Désolé, ce message s'est transformé en plusieurs questions, suivi de réponses «peut-être».

Luke Hutton
la source
FYI: Dernières meilleures pratiques autour de TLS: docs.microsoft.com/en-us/dotnet/framework/network-programming/…
JohnLBevan
Pour ceux qui veulent voir la meilleure réponse à cela, triez par votes!
navule
1
Questions et réponses sur les SO connexes: stackoverflow.com/questions/41618766/… Les lecteurs doivent noter que cette question vieillit et que des recommandations plus récentes sont en place à partir de 2020.
Pas de remboursement Pas de retour

Réponses:

281

Certains de ceux qui ont laissé des commentaires ont noté que System.Net.ServicePointManager.SecurityProtocol de valeurs spécifiques signifie que votre application ne pourra pas tirer parti des futures versions de TLS qui pourraient devenir les valeurs par défaut dans les 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 qui vous intéressent, 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;
Scott
la source
6
C'est vraiment la bonne réponse. La réponse acceptée garantira que votre application désactivera toujours les nouvelles versions TLS, sauf si vous revenez en arrière et mettez à jour votre code.
Connor
5
@Gertsen Non, c'est un bit ou, donc il active simplement les bits appropriés s'ils sont désactivés. Si ces bits sont déjà activés, aucun changement ne se produit.
Scott
3
Et l'équivalent PowerShell de ceci est [Net.ServicePointManager]::SecurityProtocol = ([Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls11 -bor [Net.SecurityProtocolType]::Tls12) Invoke-RestMethod s'appuie sur les mêmes bibliothèques de framework .NET sous-jacentes.
Martin Hollingsworth
15
Étant donné que personne ne parle de l'endroit où placer ce code, je l'ai correctement placé dans Application_Start de Global.asax.cs pour mon application ASP.NET MVC. Je cherchais comment obtenir mes demandes SMTP à envoyer sur TLS1.2 et NON sur TLS1.0. J'ai également ajouté & = ~ SecurityProtocolType.Tls pour désactiver TLS 1.0
Greg Veres
2
En VB, l'équivalent estNet.ServicePointManager.SecurityProtocol = Net.ServicePointManager.SecurityProtocol OR Net.SecurityProtocolType.Tls12 OR Net.SecurityProtocolType.Tls12
Codepaced
188

La valeur System.Net.ServicePointManager.SecurityProtocolpar défaut dans les deux .NET 4.0/4.5est SecurityProtocolType.Tls|SecurityProtocolType.Ssl3.

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

Cependant, un ciblage d'application .NET 4.0peut toujours prendre en charge jusqu'à TLS 1.2s'il .NET 4.5est installé dans le même environnement. .NET 4.5installe par-dessus .NET 4.0, remplaceSystem.dll .

J'ai vérifié cela en observant le protocole de sécurité correct défini dans le trafic avec fiddler4et en définissant manuellement les valeurs énumérées dans un .NET 4.0projet:

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 de pirater un environnement avec UNIQUEMENT .NET 4.0installé, vous obtiendrez l'exception:

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

Cependant, je ne recommanderais pas ce "hack" car un futur patch, etc. pourrait le casser. *

Par conséquent, j'ai décidé que la meilleure façon de supprimer le support SSLv3est de:

  1. Mettez à niveau toutes les applications vers .NET 4.5
  2. Ajoutez ce qui suit pour booster le code pour remplacer la valeur par défaut et la pérenniser:

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

* Quelqu'un me corrige si ce hack est faux, mais les premiers tests je vois que ça marche

Luke Hutton
la source
6
Veuillez consulter imperialviolet.org/2014/12/08/poodleagain.html "Cela semble être un bon moment pour répéter que tout ce qui est inférieur à TLS 1.2 avec une suite de chiffrement AEAD est cryptographiquement cassé."
Neil
3
@Mathew, en consultant le code source de ServicePointManager.csvoir referencesource.microsoft.com/#System/net/System/Net/…
Luke Hutton
12
Je continue de voir des gens réclamer les .NET 4.5valeurs par défaut de Tls12 - mais comme vous l'avez indiqué ici, ce n'est pas le cas. Il vous donne la possibilité de l'utiliser pourSecurityProtocol
Don Cheadle
17
Je ne rejeterai pas cette réponse car elle fournit beaucoup d'informations utiles, mais la mise en œuvre d'une version de protocole codée en dur n'est pas une bonne idée car elle empêchera l'application d'utiliser le meilleur cryptage disponible et peut entraîner des problèmes de sécurité sur la route. Le registre change pour changer le comportement par défaut de .Net pour réellement prendre en charge les protocoles modernes est très préférable. (Il convient toutefois de noter que la modification du registre désactive également SSL v3.)
AJ Henderson
6
Sur FW 4.6 et 4.7, la valeur par défaut est maintenant SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12selon support.microsoft.com/en-us/help/3069494/…
Ian Kemp
68

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

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

et

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

Pour plus de détails, veuillez consulter la mise en œuvre deServicePointManager .

Jiri Mares
la source
Merci, je n'en savais rien. Je vais le tester. J'ai créé un script powershel pour le définir: gist.github.com/lukehutton/ab80d207172a923401b1
Luke Hutton
6
Changer de registre ne semble pas être une bonne solution. Si l'application souhaite prendre en charge TLS1, l'application doit en tenir compte. Pas l'environnement en cours d'exécution. Sinon, cela pourrait endommager d'autres applications ou faire un enfer du déploiement et de la mise à niveau de votre application.
Mikhail G
13
@MikhailG bien au contraire. La modification du registre est la méthode préférable. SChannel fournit une abstraction de la négociation sous-jacente et vous souhaitez que votre application utilise le niveau de sécurité le plus élevé pris en charge. La limiter artificiellement dans le logiciel entraîne des problèmes futurs lorsque de nouveaux protocoles sont publiés et que votre logiciel n'est pas en mesure de les utiliser. Ce serait bien s'il y avait une option pour dire n'utiliser que mieux qu'un protocole donné dans le logiciel, mais il n'y a pas d'option pour cela sans empêcher également les futures versions de fonctionner. Cependant, SSL a désactivé SSL v3 avec ce changement.
AJ Henderson
13
Ligne de commande: reg add HKLM\SOFTWARE\Microsoft\.NETFramework\v4.0.30319 /v SchUseStrongCrypto /t REG_DWORD /d 1 /reg:64(et / ou /reg:32)
Kevin Smyth
7
@MikhailG: la définition du registre n'empêche pas les applications de prendre en charge les protocoles plus anciens. Il ne change que les valeurs par défaut (qui incluent tls 1.0 à partir de maintenant). De plus, le comportement par défaut dans .Net 4.6+ est d'utiliser une cryptographie forte; dans ce cas, cette entrée de registre ne serait utile que pour désactiver la cryptographie forte.
Brian
51

Créez un fichier texte avec une .regextension 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 ...

dana
la source
3
Le lien que vous avez fourni semble présenter des problèmes de certificat SSL.
NathanAldenSr
Même lorsque j'ajoute ces clés de registre, j'ai toujours ce problème. Une idée ?
Samidjo
@Samidjo - Quelle version .NET utilisez-vous? La réponse de Luke est beaucoup plus détaillée que la mienne, mais il semble que vous devez au moins avoir installé .NET 4.5. De plus, si vous venez d'effectuer la modification, vous devrez peut-être recycler le pool d'applications. Ce sont des suppositions, donc sans plus de détails, je pourrais peut-être aider beaucoup plus :)
dana
2
Un correctif récemment appliqué support.microsoft.com/en-us/help/4019114/… à un serveur a provoqué l'échec de notre application .net 4.5.2 sur les requêtes REST https. Ces clés ont résolu notre problème.
Kleinux
21

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

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

Jim
la source
2
Quel est le protocole de sécurité pris en charge sur le serveur? Je crois que c'est un facteur ici aussi et peut-être que 1.1 est le dernier sur le serveur. www.passionatecoder.ca
Ehsan
14
A voté parce que c'est la seule réponse qui indique OERE mettre la ligne de code qui est la solution.
jgerman
1
Le client (par exemple, votre client Web C #) et le serveur (serveur API que vous appelez) négocieront pour utiliser le protocole le plus élevé que les deux prennent en charge. Donc, si votre client prend en charge TLS 1.2, mais le serveur uniquement TLS 1.1 - le client utilisera TLS 1.1 (sauf si vous enlevez TLS 1.1 de votre client - dans ce cas, ils ne trouveront peut-être pas de protocole pris en charge mutuellement et le client fera une erreur)
Don Cheadle
J'ai dû ajouter en utilisant System.Net dans global.asax.cs
Patrick
16

Le code suivant:

  • protocoles activés pour l'impression
  • 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

Constantes:

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

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

Code

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

Production

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
la source
14

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. Réparer 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-et-serveur-2008-r2-sp1

Hieu
la source
1
est-il possible de changer SecurityProtocol sans changer le code source? comme un fichier machine.config ou app.config.
ahankendi
1
Sensationnel. C'est le prix vaudou de l'année ... des trucs ... juste là. Vous secouez les banlieues!
granadaCoder
14

Le mécanisme de changement de registre a fonctionné pour moi après une lutte. En fait, mon application fonctionnait en 32 bits. J'ai donc dû changer la valeur sous chemin.

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

Le type de valeur doit être DWORD et une valeur supérieure à 0. Mieux utiliser 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.

Joy George Kunjikkuru
la source
Ce n'est pas exact. Pour .NET 4.5.2, cela doit être défini sur 1 (ou supérieur); mais pour .NET 4.6, il suffit de ne pas le mettre à 0 (c'est-à-dire qu'il peut être désactivé).
Jirka Hanika
Oh, je n'ai pas testé en .Net 4.6. Mes résultats sont là dans blogpost joymonscode.blogspot.com/2015/08/…
Joy George Kunjikkuru
La clé de registre que vous mentionnez doit se lire "Wow6432Node". Vous avez omis la partie "Noeud" pour une raison quelconque. J'ai essayé de modifier votre réponse, mais mon changement n'était que de 4 lettres, donc cela ne m'a pas permis. : \
Jeffrey LeCours
J'ai dû faire rebondir IIS pour que ce paramètre soit lui-même actif par défaut.
Jeff Mitchell du
10

J'exécute 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 que SSL3, TLS 1.0 et TLS 1.1 sont tous cassé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 inspectantServicePointManager.SecurityProtocol . Sous .NET 4.7, il y a le nouveauSystemDefaultle mode de protocole qui transfère explicitement la sélection du protocole au système d'exploitation, où je pense que s'appuyer sur le registre ou d'autres paramètres de configuration du système serait approprié. Cependant, cela ne semble pas être pris en charge sous .NET 4.5.2. Dans l'intérêt d'écrire du code compatible avec les versions ultérieures, 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 la sélection d'un protocole approprié pour le 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 connu non sécurisé est activé, et dans ce cas, nous supprimerons ces protocoles non sécurisés. S'il ne reste aucun autre protocole explicite, nous forcerons alors l'activation de TLS 1.2, en tant que seul protocole sécurisé connu pris en charge par .NET à ce stade. Ce code est compatible vers l'avant, car il prendra en considération les nouveaux types de protocoles qu'il ne sait pas être ajoutés à l'avenir, et il jouera également bien avec le nouveauSystemDefaultétat dans .NET 4.7, ce qui signifie que je n'aurai pas à revisiter ce code à l'avenir. Je recommanderais fortement d'adopter une approche comme celle-ci, plutôt que de coder en dur des états de protocole de sécurité particuliers sans condition, sinon vous devrez recompiler 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 existants activés pendant des années sur votre serveur, faisant de votre organisation une cible pour les attaques.

Roger Sanders
la source
1
Cette réponse semble être la plus réfléchie, cependant, à moins que je manque quelque chose, je ne suis pas sûr qu'elle sera compatible à chaque fois que TLS 1.2 se cassera inévitablement. D'après ce que je vois dans mon application .NET 4.7.2, le SecurityProtocolType.SystemDefaultdrapeau est évalué 0, donc vérifier if (securityProtocols == 0)avec le bitwise inclus ou le drapeau pour TLS 1.2 inclura toujours TLS 1.2, même après les "pauses", n'est-ce pas? Pas de prise de vue nette ici. J'essaie vraiment de trouver la meilleure voie à suivre.
Griswald_911
J'ai modifié votre code pour inclure cela et il semble fonctionner et être compatibles avant: if (!Enum.IsDefined(typeof(SecurityProtocolType), 0) && securityProtocols == 0) { securityProtocols |= SecurityProtocolType.Tls12; }.
Griswald_911
@ Griswald_911, j'ai un code similaire dans mon application console 4.7.2, et j'ai trouvé que cette ligne securityProtocols |= SecurityProtocolType.Tls12;(sans bloc si) ne maintient pas SystemDefault, les securityProtocols n'ont que TLS2 par la suite. Donc, voulez-vous dire que lorsque la valeur est SystemDefault, aucune valeur ne doit être mise à jour? Concernant la compatibilité ascendante, supposez-vous que le système d'exploitation se chargerait d'activer un protocole plus récent comme TLS 1.3?
Yang
@Yang - Correct. L' securityProtocols |= SecurityProtocolType.Tls12;' will add TLS 1.2, but because the énumération de la ligne SecurityProtocolType` a un [Flags]attribut, et la valeur d'énumération SystemDefault est 0, la valeur SystemDefault sera supprimée, même si elle a été précédemment définie. Le résultat final est que vous pouvez soit définir la valeur SevicePointManager.SecurityProtocol 0, soit toute combinaison des autres valeurs d'énumération. Si vous le définissez sur SystemDefault, vous désactivez essentiellement la spécification du protocole vous-même et laissez le système d'exploitation décider.
Griswald_911
1
@Yang - Le fait est qu'après avoir défini la valeur sur SystemDefault, votre application doit utiliser tout ce que le système d'exploitation spécifie - qui est TLS 1.2 dans les dernières versions de Windows 10. L'idée est qu'à l'avenir, lorsque TLS 1.3 deviendra la norme, vous ne devriez pas avoir à modifier votre application pour hériter de cette fonctionnalité. Voir la documentation ici , où SystemDefault "permet au système d'exploitation de choisir le meilleur protocole à utiliser et de bloquer les protocoles qui ne sont pas sécurisés".
Griswald_911
6

Microsoft a récemment publié les meilleures pratiques à ce sujet. https://docs.microsoft.com/en-us/dotnet/framework/network-programming/tls

Résumé

Ciblez .Net Framework 4.7, supprimez tout code définissant le protocole de sécurité, ainsi le système d'exploitation vous garantira d'utiliser la solution la plus sécurisée.

NB: Vous devrez également vous assurer que la dernière version de TLS est prise en charge et activée sur votre système d'exploitation.

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

Pour plus d'informations et d'anciens cadres, veuillez vous référer au lien MS.

JohnLBevan
la source
3
Le problème est que tls 1.1 et tls 1.2 ne fonctionneront pas sur Windows 7 et Server 2008 si vous suivez les instructions (en gardant SecurityProtocolType.SystemDefault) car elles ne sont pas "activées" (quoi que cela signifie) dans ces systèmes d'exploitation sans modification du registre. Cela rend SystemDefault en pratique cassé par conception. Microsoft a vraiment foiré celui-ci.
osexpert
Bien joué, merci @osexpert, bonne prise. J'ai modifié la réponse pour inclure des informations sur les systèmes d'exploitation pris en charge, il n'y a donc pas de surprise pour les personnes utilisant des systèmes d'exploitation plus anciens où le simple ciblage de 4.7 n'est pas suffisant.
JohnLBevan
1
NB: Il existe également une base de connaissances pour activer les nouveaux protocoles sur certains systèmes d'exploitation: support.microsoft.com/en-my/help/3140245/…
JohnLBevan
1
Si les paramètres de registre ne sont pas une option, je pense que c'est la meilleure solution pour .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

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"
qbik
la source
2

Une alternative au codage en dur ServicePointManager.SecurityProtocolou à la clé SchUseStrongCrypto explicite comme mentionné ci-dessus:
Vous pouvez dire à .NET d'utiliser les paramètres 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
Alfred
la source
2

La meilleure solution à ce problème semble être de mettre à niveau au moins .NET 4.6 ou version ultérieure, qui choisira automatiquement des protocoles forts ainsi que des chiffrements solides.

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

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

Et en utilisant les paramètres du registre:

HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft.NETFramework \ v4.0.30319 - SchUseStrongCrypto = DWORD sur 1 HKEY_LOCAL_MACHINE \ SOFTWARE \ Wow6432Node \ Microsoft.NETFramework \ v4.0.30319 - SchUseStrongCrypto = DWORD

Résultats en utilisant autre chose que TLS 1.0 et un chiffrement fort.

Lors de mes tests, seul le paramètre du Wow6432Node a fait la différence, même si mon application de test a été conçue pour n'importe quel processeur.

GWC
la source
Clarification: il vous suffit de définir SevicePointManager.SecurityProtocol OU de définir les paramètres de registre. Il n'est pas nécessaire de faire les deux. Pour mon application, j'ai choisi de simplement définir ServicePointManager.SecurityProtocol. Mon raisonnement est que la définition du registre affecte la machine entière, et je ne voulais pas que l'application de quelqu'un d'autre se casse car cela dépendait de TLS 1.0.
GWC
1

Selon les meilleures pratiques de TLS (Transport Layer Security) avec le .NET Framework : Pour garantir la sécurité des applications .NET Framework, la version TLS ne doit pas être codée en dur. Définissez plutôt les clés de registre: SystemDefaultTlsVersions et 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
la source
0

Si vous pouvez utiliser .NET 4.7.1 ou une version plus récente, il utilisera TLS 1.2 comme protocole minimum en fonction des capacités du système d'exploitation. Par recommandation 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
la source
-2

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

Vous devez définir la valeur sur 1.

kgw
la source
5
Je pense que vous obtenez un vote négatif parce que c'est la même réponse offerte par @Jira Mares, mais avec moins de détails
Stuart Siegler