我需要升级.NET应用程序以支持在仅支持TLS 1.2的网站上调用API。根据我的阅读,如果应用程序的目标是4.6或更高,那么默认情况下它将使用TLS 1.2。
为了测试我创建了一个面向4.7的Windows窗体应用程序。不幸的是,当我没有明确设置ServicePointManager.SecurityProtocol时,它会出错。这是代码:
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;
}
}
}
如果您取消注释以下行:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
它有效。这不是一个好的解决方案,因为它很难编码使用的TLS版本,所以它将来不会使用TLS 1.3。
如果没有这条线,我还需要做些什么才能让它发挥作用。我在安装了4.7的Window 10机器上进行了测试。
更新
我尝试使用HttpClient进行测试并得到相同的结果,我必须明确设置SecurityProtocol。
代码:
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;
}
}
答案 0 :(得分:14)
从定位.NET Framework 4.7的应用程序开始, ServicePointManager.SecurityProtocol 属性的默认值为 SecurityProtocolType.SystemDefault 。
此更改允许基于 SslStream 的.NET Framework网络API(例如FTP,HTTPS和SMTP)从操作系统继承默认安全协议,而不是使用由.NET Framework。
这是您遇到的新行为的原因以及新配置的必要性:
<runtime>
<AppContextSwitchOverrides value="Switch.System.ServiceModel.DisableUsingServicePointManagerSecurityProtocols=false;Switch.System.Net.DontEnableSchUseStrongCrypto=false" />
</runtime>
答案 1 :(得分:8)
我找到了一个解决方案。它没有回答关于为什么TLS 1.2默认不会在Win4上使用.NET 4.7的问题,但它确实允许我不必设置ServicePointManager.SecurityProtocol。
我的4.5.2和4.7测试应用程序的解决方案是将以下内容添加到app.config:
<AppContextSwitchOverrides value="Switch.System.Net.DontEnableSchUseStrongCrypto=false"/>
整个app.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7"/>
</startup>
<runtime>
<AppContextSwitchOverrides value="Switch.System.Net.DontEnableSchUseStrongCrypto=false"/>
</runtime>
</configuration>
答案 2 :(得分:6)
作为Nick Y答案的替代方法,我发现在使用.NET 4.7+的Windows 7上,我需要启用这些注册表设置,以便Microsoft Secure Channel(Schannel)程序包正确发送TLS1.1和TLS1。 2。
这允许.NET客户端继续将System.Net.ServicePointManager.SecurityProtocol
设置为SystemDefault
并在Windows 7计算机上获得TLS 1.1和1.2。
使用SystemDefault
选项允许.NET将协议的选择推迟到OS。这意味着,当Microsoft向操作系统发布修补程序以禁用不安全的协议或在其本机SCHANNEL库中启用对新协议的支持时,运行的.NET Framework应用程序将自动获得此新行为。
这是注册表项:
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Client]
"DisabledByDefault"=dword:00000000
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client]
"DisabledByDefault"=dword:00000000
答案 3 :(得分:4)
我在Windows 7和.NET 4.7.1上
另外两个答案中提到的使用 Switch.System.ServiceModel.DisableUsingServicePointManagerSecurityProtocols 和 Switch.System.Net.DontEnableSchUseStrongCrypto 的建议在我的项目和OP的代码中均不起作用也失败了。
查看 ServicePointManager 和 LocalAppContextSwitches 的源代码我遇到了另一个有效的config setting。
<runtime>
<AppContextSwitchOverrides value="Switch.System.Net.DontEnableSystemDefaultTlsVersions=true" />
</runtime>
答案 4 :(得分:0)
对于目标为4.7.2的旧版应用程序,我遇到了相同的问题(仅Windows 10和SSL3 / TLS ...不是系统默认值)。我的问题是,在过去几年的升级过程中,我们从未将targetFramework
添加到system.web
> httpRuntime
元素中(注意:它确实存在于system.web
> {{ 1}}元素)。在采取更大的步骤之前,请确保您的system.web如下所示:
compilation
在上面的示例中,将4.7.2替换为当前使用的框架的任何版本,即> = 4.7。
答案 5 :(得分:0)
Windows 7 默认禁用 TLS1.2 和 TLS1.1。在 IE 中启用它对其他应用程序没有影响。
您应该通过注册表启用它: [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client] "DisabledByDefault"=dword:00000000