由于以下错误消息,我们无法使用WebRequest连接到HTTPS服务器:
请求被中止:无法创建SSL/TLS安全通道。
我们知道服务器没有有效的HTTPS证书,但为了绕过这个问题,我们使用下面的代码,我们从另一个StackOverflow帖子:
private void Somewhere() {
ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(AlwaysGoodCertificate);
}
private static bool AlwaysGoodCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors policyErrors) {
return true;
}
问题是服务器从未验证证书,并出现上述错误而失败。有人知道我该怎么做吗?
我应该提到的是,我和一个同事几周前进行了测试,它运行得很好,与我上面写的类似。我们发现的唯一“主要区别”是,我用的是Windows 7,而他用的是Windows XP。这会改变什么吗?
注意:这里投票最多的几个答案建议设置ServicePointManager。安全协议,但微软明确建议不要这样做。下面,我将讨论此问题的典型原因以及解决该问题的最佳实践。
这个问题的最大原因之一是活动的。net框架版本。. net框架运行时版本会影响默认启用的安全协议。
在ASP。NET站点,框架运行时版本通常在web.config中指定。(见下文)
在其他应用程序中,运行时版本通常是构建项目的版本,而不管它是否运行在具有更新的. net版本的机器上。
似乎没有任何权威的文档说明它在不同版本中是如何具体工作的,但似乎默认值或多或少是这样确定的:
Framework Version |
Default Protocols |
4.5 and earlier |
SSL 3.0, TLS 1.0 |
4.6.x |
TLS 1.0, 1.1, 1.2, 1.3 |
4.7+ |
System (OS) Defaults |
对于较旧的版本,根据系统上安装的. net运行时的不同,您的里程可能会有所不同。例如,可能会出现这样的情况,您正在使用一个非常旧的框架,不支持TLS 1.0,或者使用4.6。不支持TLS 1.3。
微软的文档强烈建议使用4.7+和系统默认值:
我们建议您:
在你的应用程序上瞄准。net Framework 4.7或更高版本。在你的WCF应用中瞄准。net Framework 4.7.1或更高版本。
不指定TLS版本。配置代码,让操作系统决定TLS版本。
执行彻底的代码审计,以验证您没有指定TLS或SSL版本。
ASP。NET站点:检查<httpRuntime>元素中的targetFramework版本,因为这个(当出现时)决定了你的站点实际使用的运行时:
<httpRuntime targetFramework="4.5" />
好:
<httpRuntime targetFramework="4.7" />
设置方法
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
看起来还可以,因为Tls1.2是最新版本的安全协议。但我决定深入研究,并回答我们是否真的需要硬编码它。
规格:Windows Server 2012R2 x64。
从互联网上得知,. net framework 4.6+必须默认使用Tls1.2。但是当我把我的项目更新到4.6时,什么都没有发生。
我找到了一些信息,告诉我需要手动做一些更改,默认启用Tls1.2
https://support.microsoft.com/en-in/help/3140245/update-to-enable-tls-1-1-and-tls-1-2-as-default-secure-protocols-in-wi
但是建议的windows更新不适用于R2版本
但是帮助我的是在注册表中添加2个值。您可以使用下一个PS脚本,这样它们就会自动添加
Set-ItemProperty -Path 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value '1' -Type DWord
Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value '1' -Type DWord
这正是我想要的。但是我仍然不能回答为什么NetFramework 4.6+没有设置这个问题…自动协议值?
这个问题可以有很多答案,因为它是关于一个通用的错误消息。我们在一些服务器上遇到了这个问题,但在开发机器上没有。拔了大部分头发后,我们发现这是微软的一个漏洞。
https://support.microsoft.com/en-us/help/4458166/applications-that-rely-on-tls-1-2-strong-encryption-experience-connect
从本质上讲,MS假定您想要较弱的加密,但操作系统被修补为只允许TLS 1.2,因此您会收到可怕的“请求被中止:无法创建SSL/TLS安全通道”。
有三个解决办法。
用适当的更新修补操作系统:http://www.catalog.update.microsoft.com/Search.aspx?q=kb4458166
在app.config/web中添加一个设置。配置文件(如上链接所述):
<runtime>
<AppContextSwitchOverrides value="Switch.System.Net.DontEnableSchUseStrongCrypto=false" />
</runtime>
添加在另一个答案中已经提到的注册表设置。
所有这些都在我发布的知识库文章中提到过。