由于以下错误消息,我们无法使用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。这会改变什么吗?
system.net.webeexception:请求被中止:无法创建
SSL/TLS安全通道。
在我们的例子中,我们使用的是软件供应商,所以我们没有权限修改。net代码。显然。net 4不会使用TLS v 1.2,除非有变化。
我们的解决方法是将SchUseStrongCrypto键添加到注册表中。您可以将下面的代码复制/粘贴到扩展名为.reg的文本文件中并执行它。它是我们解决问题的“补丁”。
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319]
"SchUseStrongCrypto"=dword:00000001
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319]
"SchUseStrongCrypto"=dword:00000001
注意:这里投票最多的几个答案建议设置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" />
Another possible cause of the The request was aborted: Could not create SSL/TLS secure channel error is a mismatch between your client PC's configured cipher_suites values, and the values that the server is configured as being willing and able to accept. In this case, when your client sends the list of cipher_suites values that it is able to accept in its initial SSL handshaking/negotiation "Client Hello" message, the server sees that none of the provided values are acceptable, and may return an "Alert" response instead of proceeding to the "Server Hello" step of the SSL handshake.
为了研究这种可能性,您可以下载Microsoft Message Analyzer,并使用它来跟踪当您尝试建立到服务器的HTTPS连接失败时(在c#应用程序中)发生的SSL协商。
如果您能够从另一个环境(例如您提到的Windows XP机器)成功建立HTTPS连接,或者可能通过在不使用操作系统加密套件设置的非微软浏览器(如Chrome或Firefox)中点击HTTPS URL,则在该环境中运行另一个Message Analyzer跟踪,以捕获SSL协商成功时发生的情况。
希望您能看到两个Client Hello消息之间的一些区别,从而能够准确地指出失败的SSL协商是什么原因导致它失败的。然后,您应该能够对Windows进行配置更改,以使其成功。IISCrypto是一个很好的工具(即使对于客户端pc,尽管它叫“IIS”)。
以下两个Windows注册表项控制你的电脑将使用的cipher_suites值:
微软HKLM \ SOFTWARE \政策\ \ SSL加密\ Configuration \ \ 00010002
HKLM \ SYSTEM \ CurrentControlSet \ \控制密码学\ \当地\ SSL配置\ 00010002
以下是我如何调查和解决这种无法创建SSL/TLS安全通道问题的实例的完整记录:http://blog.jonschneider.com/2016/08/fix-ssl-handshaking-error-in-windows.html
在我的例子中,当一个Windows服务试图连接到一个web服务时,我遇到了这个问题。在Windows事件中,我终于找到了一个错误代码。
事件ID 36888(通道)被引发:
The following fatal alert was generated: 40. The internal error state is 808.
最后,它与Windows热修复有关。在我的例子中是KB3172605和KB3177186
vmware论坛提出的解决方案是在windows中添加一个注册表项。添加以下注册表后,所有工作正常。
[HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ \控制SecurityProviders \ SCHANNEL \ KeyExchangeAlgorithms \ diffie - hellman)
“ClientMinKeyBitLength”= dword: 00000200
显然,这与客户端https握手中缺失的值有关。
列出你的Windows HotFix:
wmic qfe list
解决方案线程:
https://communities.vmware.com/message/2604912#2604912
希望对大家有所帮助。