C# 请求被中止:无法创建SSL/TLS安全通道

C# 请求被中止:无法创建SSL/TLS安全通道,c#,asp.net,windows-8,windows-7,httpwebrequest,C#,Asp.net,Windows 8,Windows 7,Httpwebrequest,由于以下错误消息,我们无法使用WebRequest连接到HTTPS服务器: 请求被中止:无法创建SSL/TLS安全通道。 我们知道服务器没有使用路径的有效HTTPS证书,但为了绕过此问题,我们使用从另一篇StackOverflow文章中获取的以下代码: private void Somewhere() { ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCa

由于以下错误消息,我们无法使用
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;
}
问题是,服务器从不验证证书,并且由于上述错误而失败。有人知道我该怎么做吗



我应该提到的是,几周前我和一位同事进行了测试,测试结果与我上面写的类似。我们发现的唯一“主要区别”是我使用的是Windows7,而他使用的是WindowsXP。这会改变什么吗?

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

有关如何设置的示例,请访问:

在更多信息中的步骤2下


编辑:在较新版本的IIS中,此功能内置于证书管理器工具中,可以通过右键单击证书并使用用于管理私钥的选项来访问。此处有更多详细信息:

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

最好的解决方案是使用SChannel故障排除工具集。SChannel是负责SSL和TLS的SSPI提供商,您的客户将使用它进行握手。看一看


另请参见。

我终于找到了答案(我没有指出我的来源,但它来自搜索)

当代码在Windows XP中运行时,在Windows 7中,必须在开头添加以下内容:

// using System.Net;
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
// Use SecurityProtocolType.Ssl3 if needed for compatibility reasons
现在,它工作得很好


附录


正如罗宾·弗伦奇所提到的;如果您在配置PayPal时遇到此问题,请注意,从2018年12月3日起,他们将不支持SSL3。您需要使用TLS。这里是关于它的。

另一种可能是盒子上的证书输入不正确。确保选中“环绕”复选框。起初我并没有这样做,所以代码要么超时,要么抛出相同的异常,因为无法找到私钥


正如您所知,发生这种情况的原因很多。我想我会加上我遇到的原因

如果将
WebRequest.Timeout
的值设置为
0
,则会引发此异常。下面是我的代码。。。(除了超时值不是硬编码的
0
,我有一个参数无意中被设置为
0

“请求已中止:无法创建SSL/TLS安全通道”如果服务器对HTTP请求返回HTTP 401未经授权的响应,则可能发生异常

您可以通过为客户端应用程序打开跟踪级别的System.Net日志记录来确定是否发生这种情况,如中所述

一旦日志配置就位,运行应用程序并再现错误,然后在日志输出中查找如下行:

System.Net Information: 0 : [9840] Connection#62912200 - Received status line: Version=1.1, StatusCode=401, StatusDescription=Unauthorized.
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
new WebClient().DownloadData("https://ct.mob0.com/Styles/Fun.png");
   var certificate = new X509Certificate2(bytes, pass);
   var certificate = new X509Certificate2(bytes, pass, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);

在我的情况下,我未能设置服务器期望的特定cookie,导致服务器响应请求时出现401错误,这反过来导致“无法创建SSL/TLS安全通道”异常。

我在尝试命中时遇到此问题,这是CloudFlare在其CDN上发布的一个映像,它支持疯狂的东西,如SPDY和怪异的重定向SSL证书

我没有像Simons answer中那样指定Ssl3,而是通过如下方式转到Tls12来修复它:

System.Net Information: 0 : [9840] Connection#62912200 - Received status line: Version=1.1, StatusCode=401, StatusDescription=Unauthorized.
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
new WebClient().DownloadData("https://ct.mob0.com/Styles/Fun.png");
   var certificate = new X509Certificate2(bytes, pass);
   var certificate = new X509Certificate2(bytes, pass, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);

在长时间处理同一问题后,我发现运行客户端服务的ASP.NET帐户无法访问证书。我通过进入运行web应用程序的IIS应用程序池,进入高级设置,并将身份从
NetworkService
更改为
LocalSystem
帐户来修复它


更好的解决方案是让证书与默认的
NetworkService
帐户一起工作,但这对快速功能测试有效。

我的问题是,我试图在IIS上部署web服务,我在服务器上安装了证书,但是运行IIS的用户没有对证书的正确权限


我整天都在与这个问题作斗争

当我用.NET 4.5创建一个新项目时,我终于让它开始工作了。

但如果我降级到4.0,我又会遇到同样的问题,这对那个项目来说是不可逆转的(即使我再次尝试升级到4.5)


奇怪的是,除了“请求已中止:无法创建SSL/TLS安全通道”之外,没有其他错误消息。出现此错误的原因是原始答案没有。我添加了更多的代码以使其防弹

ServicePointManager.Expect100Continue = true;
        ServicePointManager.DefaultConnectionLimit = 9999;
        ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 | SecurityProtocolType.Ssl3;

请求被中止的另一个可能原因是:无法创建SSL/TLS安全通道
错误是客户端PC配置的密码套件值与服务器配置为愿意且能够接受的值不匹配。在这种情况下,当您的客户端发送它能够在其初始SSL握手/协商“client Hello”消息中接受的cipher_Suite值列表时,服务器会发现所提供的值都不可接受,并且可能会返回“Alert”响应,而不是继续到
ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;
ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;

XmlReader r = XmlReader.Create(url);
SyndicationFeed albums = SyndicationFeed.Load(r);
https://www.fbi.gov/feeds/fbi-in-the-news/atom.xml
https://www.wired.com/feed/category/gear/latest/rss
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;
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
   var certificate = new X509Certificate2(bytes, pass);
   var certificate = new X509Certificate2(bytes, pass, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
// 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...
}
<httpRuntime targetFramework="4.5" />
<httpRuntime targetFramework="4.7" />
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
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
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;