TLS 1.2 ne sont pas négociés sur .NET de 4,7 sans explicites ServicePointManager.SecurityProtocol appel
J'ai besoin de mettre à niveau un .NET application pour prendre en charge un appel à une API sur un site qui ne prend en charge TLS 1.2. De ce que j'ai lu, si l'application cible 4.6 ou plus, alors, il va utiliser le protocole TLS 1.2 par défaut.
Pour tester, j'ai créé une application Windows Forms qui cible 4.7. Malheureusement, il erreurs lorsque je n'ai pas explicitement défini ServicePointManager.SecurityProtocol. Voici le code:
HttpClient _client = new HttpClient();
var msg = new StringBuilder();
//If I uncomment the next line it works, but fails even with 4.7
//ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
var httpWebRequest = (HttpWebRequest)WebRequest.Create("https://sandbox.authorize.net");
httpWebRequest.KeepAlive = false;
try
{
var httpWebResponse = (HttpWebResponse) httpWebRequest.GetResponse();
msg.AppendLine("The HTTP request Headers for the first request are: ");
foreach (var header in httpWebRequest.Headers)
{
msg.AppendLine(header.ToString());
}
ResponseTextBox.Text = msg.ToString();
}
catch (Exception exception)
{
ResponseTextBox.Text = exception.Message;
if (exception.InnerException != null)
{
ResponseTextBox.Text += Environment.NewLine + @" ->" + exception.InnerException.Message;
if (exception.InnerException.InnerException != null)
{
ResponseTextBox.Text += Environment.NewLine + @" ->" + exception.InnerException.InnerException.Message;
}
}
}
Si vous décommentez la ligne suivante:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
il fonctionne. Ce n'est pas une bonne solution, car il est difficile de codes quels TLS version à utiliser, donc il ne serait pas utiliser le protocole TLS 1.3 dans l'avenir.
De quoi dois-je faire pour le faire fonctionner sans avoir cette ligne. Je suis en essais à partir d'une Fenêtre de 10 machine avec 4,7 installé.
Mise à jour
J'ai essayé un test avec HttpClient et avaient les mêmes résultats, j'ai eu à définir explicitement SecurityProtocol.
Code:
var msg = new StringBuilder();
//Need to uncomment code below for TLS 1.2 to be used
//ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
try
{
var response = await _client.GetAsync(@"https://sandbox.authorize.net");
msg.AppendLine("response.IsSuccessStatusCode : " + response.IsSuccessStatusCode);
msg.AppendLine(await response.Content.ReadAsStringAsync());
textBox.Text = msg.ToString();
}
catch (Exception exception)
{
textBox.Text = exception.Message;
if (exception.InnerException != null)
{
textBox.Text += Environment.NewLine + @" ->" + exception.InnerException.Message;
}
}
Je ne veux pas de définir le protocole de sécurité parce que quand un nouveau, tels que TLS 1.3 devient disponible, il ne sera pas utilisé car il n'est pas dans la liste. Je vais réécrire mon test avec HttpClient, quel est le Protocole de Sécurité par défaut utilisé par HttpClient vs HttpWebResponse?
Ne prenez pas mon mot pour lui, mais je suppose HttpClient aurez en charge la négociation de la plus haute protocole disponible pour la version du CLR. Donc, votre prochaine mur de briques besoin d'un CLR mise à niveau au lieu de mise à niveau du code. C'est probablement une idée horrible, mais je me demande ce qui se passera si vous venez de tourner sur tous les bits:
SecurityProtocolType s = (SecurityProtocolType)2147483647;
même résultat avec HttpClient, mis à jour en question le code utilisé.
Intéressant. Découvrez cette version note à propos de la v4.7 github.com/Microsoft/dotnet/blob/master/releases/net47/...
OriginalL'auteur Josh | 2017-06-25
Vous devez vous connecter pour publier un commentaire.
De départ avec les apps qui cible les .NET Framework 4.7, la valeur par défaut de la ServicePointManager.SecurityProtocol propriété est SecurityProtocolType.SystemDefault.
Ce changement permet .NET Framework Api de réseau basé sur SslStream (tels que FTP, HTTPS, SMTP) pour hériter de la valeur par défaut des protocoles de sécurité du système d'exploitation au lieu d'utiliser les valeurs absolues définies par l' .NET Framework.
C'est la raison de ces nouveaux comportements que vous avez subi et la nécessité de la nouvelle configuration:
Voir ici et ici
OriginalL'auteur Gianpiero Caretti
J'ai trouvé une solution. Il ne répond pas à la question pourquoi TLS 1.2 n'est pas utilisé par défaut sur Win10 .NET 4.7, mais il ne me permettent pas d'avoir à définir ServicePointManager.SecurityProtocol.
La solution qui a fonctionné à partir de mon 4.5.2 et 4.7 test apps est d'ajouter les éléments suivants à l'app.config:
Ici l'ensemble de l'application.config:
J'ai essayé ceci dans une application console qui fait un
HttpClient
demande à un TLS 1.2 web-service, et j'ai exécuté le programme en mode console sous Windows 7 SP1. Malheureusement, il y avait zéro effet. Downvoting.OriginalL'auteur Josh
Comme une alternative à Nick d'Y répondre, j'ai découvert que sur Windows 7 à l'aide .NET de 4,7+, j'nécessaire pour permettre à ces paramètres de registre pour Microsoft Secure Channel (Schannel) à envoyer correctement TLS1.1 et TLS1.2.
Cela permet à l' .NET client de continuer à avoir
System.Net.ServicePointManager.SecurityProtocol
ensemble deSystemDefault
et obtenir TLS 1.1 et 1.2 sur un ordinateur Windows 7.À l'aide de la
SystemDefault
option permet .NET de reporter la sélection de protocoles de de l'OS. Cela signifie que lorsque Microsoft publie des correctifs pour le système d'exploitation pour désactiver l'insécurité des protocoles ou active le support pour les nouveaux natif SCHANNEL bibliothèque .NET framework applications en cours d'exécution sera automatiquement ce nouveau comportement.Voici les entrées de registre:
pas de. Si vous réglez "DontEnableSystemDefaultTlsVersion=true", vous désactivez le système d'exploitation par défaut de protocoles et d'activer uniquement les protocoles par défaut dans la version installée .NET. Dans mon cas, Si l'OS est corrigé pour permettre à de nouveaux protocoles, je veux activé. Je ne voulais pas de mise à jour de l'application de config ou .NET framework version juste pour permettre de nouvelles versions de TLS.
Voir mon jour de réponse quant à pourquoi il peut être avantageux vs modification de l'application pour désactiver le SystemDefault.
Je fais remarquer que cela pourrait être un OS de problème de configuration, pas une .NET problème d'application.
D'accord avec Merick, à l'aide de SystemDefault est recommandé par Microsoft et permettant plus récente version de TLS doit être le travail de mise à jour de windows/correctif;
OriginalL'auteur MerickOWA
Je suis sur Windows 7 et .NET 4.7.1
La recommandation de l'utilisation de Commutateur.Système.ServiceModel.DisableUsingServicePointManagerSecurityprotocols et Commutateur.Système.Net.DontEnableSchUseStrongCrypto mentionné dans deux autres réponses n'ont pas de travail dans mon projet et OP du code n'était pas de trop.
L'examen de code source pour ServicePointManager et LocalAppContextSwitches je suis tombé sur un autre paramètre de configuration qui a fonctionné.
Ce paramètre de configuration qui fonctionne pour l'application de la console. Application Web de ciblage de 4.7 ou au-dessus auront toujours du Système.Net.ServicePointManager.SecurityProtocol = SystemDefault sauf s'il est codé en dur explicitement à d'autres protocoles (qui n'est pas recommandé)
OriginalL'auteur Nick Y