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


当前回答

我有这个问题是因为我的网。配置:

<httpRuntime targetFramework="4.5.2" />

而不是:

<httpRuntime targetFramework="4.6.1" />

其他回答

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

对我来说,这只是发生在一个网站上,结果是它只有RC4密码可用。在之前加强服务器的努力中,我禁用了RC4密码,一旦我重新启用这个问题就解决了。

没有一个答案对我有用。

这是有效的方法:

而不是像这样初始化我的X509Certifiacte2:

   var certificate = new X509Certificate2(bytes, pass);

我是这样做的:

   var certificate = new X509Certificate2(bytes, pass, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);

注意X509KeyStorageFlags。出口! !

我没有改变其余的代码(WebRequest本身):

// I'm not even sure the first two lines are necessary:
ServicePointManager.Expect100Continue = true; 
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

request = (HttpWebRequest)WebRequest.Create(string.Format("https://{0}.sii.cl/cvc_cgi/dte/of_solicita_folios", server));
request.Method = "GET";
request.Referer = string.Format("https://hercules.sii.cl/cgi_AUT2000/autInicio.cgi?referencia=https://{0}.sii.cl/cvc_cgi/dte/of_solicita_folios", servidor);
request.UserAgent = "Mozilla/4.0";
request.ClientCertificates.Add(certificate);
request.CookieContainer = new CookieContainer();

using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
    // etc...
}

事实上,我甚至不确定前两行是否有必要……

您遇到的问题是aspNet用户没有访问证书的权限。您必须使用winhttpcertcfg.exe提供访问权限

关于如何设置的示例如下: http://support.microsoft.com/kb/901183

详细信息请参见步骤2

编辑:在最新版本的IIS中,此功能内置于证书管理器工具中-可以通过右键单击证书并使用管理私钥的选项来访问。更多详情请访问:https://serverfault.com/questions/131046/how-to-grant-iis-7-5-access-to-a-certificate-in-certificate-store/132791#132791

这个错误是一般的,有很多原因导致SSL/TLS协商失败。最常见的是无效或过期的服务器证书,您可以通过提供自己的服务器证书验证钩子来解决这个问题,但这并不一定是唯一的原因。服务器可能需要相互身份验证,它可能配置了一组客户端不支持的密码,它可能有太大的时间漂移,以至于握手无法成功,还有很多其他原因。

最好的解决方案是使用channel故障排除工具集。channnel是负责SSL和TLS的SSPI提供者,您的客户端将使用它进行握手。看看TLS/SSL工具和设置。

另请参阅如何启用通道事件日志记录。