由于以下错误消息,我们无法使用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。这会改变什么吗?


当前回答

我终于找到了答案(我没有注明我的来源,但它来自一次搜索);

虽然代码在Windows XP中工作,但在Windows 7中,你必须在开头添加这个:

// using System.Net;
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
// Use SecurityProtocolType.Ssl3 if needed for compatibility reasons

现在,它工作得很完美。


齿顶高

Robin French提到过;如果你在配置PayPal时遇到了这个问题,请注意从2018年12月3日开始他们将不支持SSL3。您需要使用TLS。这是关于它的Paypal页面。

其他回答

在我的例子中,当一个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

希望对大家有所帮助。

另一种可能是正在执行的代码没有所需的权限。

在我的例子中,我在使用Visual Studio调试器测试对web服务的调用时得到了这个错误。Visual Studio没有以管理员身份运行,这导致了此异常。

这些答案都不适合我,谷歌chrome和邮递员工作,握手服务器,但ie和。net不工作。在谷歌chrome在安全选项卡>连接显示加密和认证使用ECDHE_RSA与P-256和AES_256_GCM密码套件与服务器握手。

我在windows server 2012 R2上安装了IIS密码和密码套件列表,无法找到带有P-256和AES_256_GCM密码套件的ECDHE_RSA。然后我把Windows更新到上一个版本,但问题没有解决。最后在搜索之后,我明白了windows server 2012 R2不支持GSM,并将我的服务器更新到windows server 2016,我的问题解决了。

另一种可能是箱子上的证书输入不当。请确保选中周围的复选框。最初我没有这样做,所以代码要么超时,要么抛出相同的异常,因为私钥无法定位。

在我的情况下,这个异常的根源是在代码的某些时候,下面的代码被调用:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;

这真的很糟糕。它不仅指示. net使用不安全的协议,而且还会影响在您的应用域中随后发出的每一个新的WebClient(和类似的)请求。(请注意,传入的web请求在你的ASP中不受影响。NET应用程序,但新的WebClient请求,如与外部web服务对话,是)。

在我的情况下,它实际上并不需要,所以我可以删除该语句,所有其他的web请求重新开始正常工作。根据我在其他地方的阅读,我了解到一些事情:

This is a global setting in your appdomain, and if you have concurrent activity, you can't reliably set it to one value, do your action, and then set it back. Another action may take place during that small window and be impacted. The correct setting is to leave it default. This allows .NET to continue to use whatever is the most secure default value as time goes on and you upgrade frameworks. Setting it to TLS12 (which is the most secure as of this writing) will work now but in 5 years may start causing mysterious problems. If you really need to set a value, you should consider doing it in a separate specialized application or appdomain and find a way to talk between it and your main pool. Because it's a single global value, trying to manage it within a busy app pool will only lead to trouble. This answer: https://stackoverflow.com/a/26754917/7656 provides a possible solution by way of a custom proxy. (Note I have not personally implemented it.)