由于以下错误消息,我们无法使用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。这会改变什么吗?
这个问题可以有很多答案,因为它是关于一个通用的错误消息。我们在一些服务器上遇到了这个问题,但在开发机器上没有。拔了大部分头发后,我们发现这是微软的一个漏洞。
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>
添加在另一个答案中已经提到的注册表设置。
所有这些都在我发布的知识库文章中提到过。
我最近也遇到了同样的问题。我的环境运行在。net 4.6.1和VB.NET下。这就是我解决问题的方法:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3
ServicePointManager.ServerCertificateValidationCallback = New RemoteCertificateValidationCallback(AddressOf util.ValidateServerCertificate)
还有util。ValidateServerCertificate函数为:
Public Function ValidateServerCertificate(ByVal sender As Object, ByVal certificate As X509Certificate, ByVal chain As X509Chain, ByVal sslPolicyErrors As SslPolicyErrors) As Boolean
Return True
End Function
如果服务器对HTTP请求返回HTTP 401未授权响应,则会出现“请求已终止:无法创建SSL/TLS安全通道”异常。
您可以通过打开跟踪级系统来确定是否发生这种情况。Net日志记录用于客户端应用程序,如本回答中所述。
一旦日志配置就绪,运行应用程序并重现错误,然后在日志输出中查找如下一行:
System.Net Information: 0 : [9840] Connection#62912200 - Received status line: Version=1.1, StatusCode=401, StatusDescription=Unauthorized.
在我的情况下,我未能设置服务器所期望的特定cookie,导致服务器以401错误响应请求,从而导致“无法创建SSL/TLS安全通道”异常。
确保ServicePointManager设置是在创建HttpWebRequest之前完成的,否则它将无法工作。
工作原理:
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls
| SecurityProtocolType.Tls11
| SecurityProtocolType.Tls12
| SecurityProtocolType.Ssl3;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://google.com/api/")
失败:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://google.com/api/")
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls
| SecurityProtocolType.Tls11
| SecurityProtocolType.Tls12
| SecurityProtocolType.Ssl3;