我们无法使用以下方式连接到 HTTPS 服务器 WebRequest 因为这个错误消息:

The request was aborted: Could not create SSL/TLS secure channel.

我们知道服务器没有包含所使用路径的有效 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

现在,它运作完美。


附录

如罗宾·法国人所提到的;如果您在配置PayPal时遇到此问题,请注意,他们将不支持2018年12月3日开始。您需要使用TLS。这是 贝宝页 关于它。

其他提示

解决方案,.NET 4.5是

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

如果您没有.NET 4.5,请使用

ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;

确保在创建httpwebrequest之前进行ServicePointManager设置,否则它将无法使用。

作品:

        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;

您遇到的问题是ASPNET用户无法访问证书。您必须使用winhttpcertcfg.exe提供访问权限

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

根据步骤2的更多信息

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

错误是通用的,因此SSL/TLS谈判可能失败的原因有很多。最常见的是无效或过期的服务器证书,您通过提供自己的服务器证书验证挂钩来解决此问题,但不一定是唯一的原因。服务器可能需要相互验证,它可能配置为客户不支持的密码套件,它可能会漂移太大,无法成功,还有更多原因。

最好的解决方案是使用Schannel故障排除工具集。 Schannel是负责SSL和TLS的SSPI提供商,您的客户将其用于握手。看一眼 TLS/SSL工具和设置.

也看 如何启用Schannel事件记录.

我遇到了这个问题 https://ct.mob0.com/styles/fun.png, ,这是Cloudflare在其CDN上分发的图像,支持SPDY和怪异的重定向SSL证书等疯狂的东西。

与其指定SSL3如Simons答案中,我能够通过这样的tls12来解决它:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
new WebClient().DownloadData("https://ct.mob0.com/Styles/Fun.png");

经过很多时间,我发现客户服务正在运行的ASP.NET帐户无法访问证书。我通过进入Web应用程序运行的IIS应用程序池,进入高级设置并将身份更改为 LocalSystem 帐户来自 NetworkService.

一个更好的解决方案是使证书与默认 NetworkService 帐户,但这用于快速功能测试。

原始答案没有的东西。我添加了更多代码以使其成为子弹的证明。

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

另一种可能性是在框中进口证书不当。确保选择包围的复选框。最初,我没有这样做,因此代码要么是按时出现的,要么抛出与私钥无法找到的异常。

certificate importation dialog

如果服务器正在返回,则可能会出现“中止请求:无法创建SSL/TLS安全频道” HTTP 401未经授权 对HTTP请求的响应。

您可以通过打开trace level system.net记录客户应用程序来确定是否发生这种情况,如图所述 这个答案.

一旦到达日志记录配置,请运行应用程序并重现错误,然后在记录输出中查看这样的行:

System.Net Information: 0 : [9840] Connection#62912200 - Received status line: Version=1.1, StatusCode=401, StatusDescription=Unauthorized.

在我的情况下,我未能设置服务器所期望的特定cookie,导致服务器以401错误响应了该请求,这反过来又导致了“无法创建SSL/TLS Secure Channel”。

在我的情况下,此例外的根源是,在代码中的某个时刻被调用:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;

这真的很糟糕。它不仅指示.NET使用不安全协议,而且会影响您的AppDomain之后的每个新的网络客户(和类似)请求。 (请注意,传入的Web请求在您的ASP.NET应用中不受影响,但是与外部Web Service交谈的新WebClient请求是)。

就我而言,实际上并不需要它,因此我可以删除该声明,而我所有的其他Web请求再次开始正常工作。根据我在其他地方的阅读,我学到了一些知识:

  • 这是AppDomain中的全局设置,如果您有同时进行活动,则无法可靠地将其设置为一个值,执行操作,然后将其设置回。在那个小窗口期间可能会采取另一个动作并受到影响。
  • 正确的设置是将其默认。这允许.NET随着时间的流逝,您可以继续使用最安全的默认值并升级框架。将其设置为TLS12(截至撰写本文时最安全)将有效 现在 但是在5年内,可能会开始引起神秘的问题。
  • 如果您确实需要设置一个值,则应考虑在单独的专业应用程序或AppDomain中进行此操作,并找到一种在其和主池之间进行交谈的方法。因为它是一个单一的全球价值,所以尝试在繁忙的应用程序池中管理它只会导致麻烦。这个答案: https://stackoverflow.com/a/26754917/7656 通过自定义代理提供了可能的解决方案。 (请注意,我没有亲自实施它。)

这个在MVC WebClient中为我工作

    public string DownloadSite(string RefinedLink)
    {
        try
        {
            Uri address = new Uri(RefinedLink);

            ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;

            System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

            using (WebClient webClient = new WebClient())
            {
                var stream = webClient.OpenRead(address);
                using (StreamReader sr = new StreamReader(stream))
                {
                    var page = sr.ReadToEnd();

                    return page;
                }
            }

        }
        catch (Exception e)
        {
            log.Error("DownloadSite - error Lin = " + RefinedLink, e);
            return null;
        }
    }

如您所知,这可能发生很多原因。以为我会添加我遇到的原因...

如果设置值 WebRequest.Timeout0, ,这是抛出的例外。以下是我拥有的代码(除非是硬编码 0 对于超时值,我有一个无意中的参数 0).

WebRequest webRequest = WebRequest.Create(@"https://myservice/path");
webRequest.ContentType = "text/html";
webRequest.Method = "POST";
string body = "...";
byte[] bytes = Encoding.ASCII.GetBytes(body);
webRequest.ContentLength = bytes.Length;
var os = webRequest.GetRequestStream();
os.Write(bytes, 0, bytes.Length);
os.Close();
webRequest.Timeout = 0; //setting the timeout to 0 causes the request to fail
WebResponse webResponse = webRequest.GetResponse(); //Exception thrown here ...

另一个可能的原因是 The request was aborted: Could not create SSL/TLS secure channel 错误是一个 客户端 PC 配置的 cipher_suites 值与服务器配置为愿意且能够接受的值之间不匹配. 。在这种情况下,当您的客户端发送它能够在其初始 SSL 握手/协商“Client Hello”消息中接受的 cipher_suites 值列表时,服务器会发现所提供的值均不可接受,并且可能会返回“Alert” ”响应,而不是继续进行 SSL 握手的“服务器问候”步骤。

要调查这种可能性,您可以下载 微软消息分析器, ,并使用它对当您尝试与服务器建立 HTTPS 连接但失败时(在 C# 应用程序中)发生的 SSL 协商运行跟踪。

如果您能够从另一个环境(例如,您提到的 Windows XP 计算机,或者可能通过在不使用操作系统的密码套件设置的非 Microsoft 浏览器(例如 Chrome 或 Firefox)中点击 HTTPS URL,在该环境中运行另一个消息分析器跟踪来捕获SSL 协商成功后会发生什么。

希望您会看到两个 Client Hello 消息之间的一些差异,这将使您能够准确地查明失败的 SSL 协商导致其失败的原因。然后您应该能够对 Windows 进行配置更改以使其成功。 II加密 是一个很棒的工具(即使对于客户端 PC,尽管名称为“IIS”)。

以下两个 Windows 注册表项控制您的 PC 将使用的 cipher_suites 值:

  • HKLM\SOFTWARE\Policies\Microsoft\Cryptography\Configuration\SSL\00010002
  • HKLM\SYSTEM\CurrentControlSet\Control\Cryptography\Configuration\Local\SSL\00010002

这是我如何调查和解决此类问题的一个完整的文章 Could not create SSL/TLS secure channel 问题: http://blog.jonschneider.com/2016/08/fix-ssl-handshaking-error-in-windows.html

我整天都在为这个问题而苦苦挣扎。

当我使用.NET 4.5创建一个新项目时,我终于使它起作用。

但是,如果我降级到4.0,我再次遇到了同样的问题,对于该项目来说,这是不可逆转的(即使我试图再次升级到4.5)。

奇怪的没有其他错误消息,但是 “该请求被中止:无法创建SSL/TLS安全渠道。” 出现这个错误

如果客户端是Windows计算机,则可能的原因可能是服务所需的TLS或SSL协议未被激活。

这可以设置为:

控制面板 - >网络和互联网 - > Internet选项 - >高级

滚动设置为“安全”,然后在

  • 使用SSL 2.0
  • 使用SSL 3.0
  • 使用TLS 1.0
  • 使用TLS 1.1
  • 使用TLS 1.2

enter image description here

我有这个问题,因为我的web.config有:

<httpRuntime targetFramework="4.5.2" />

并不是:

<httpRuntime targetFramework="4.6.1" />

就我而言,运行该应用程序的服务帐户无权访问私钥。一旦我给予此许可,错误就消失了

  1. MMC
  2. 证书
  3. 扩展到个人
  4. 选择证书
  5. 右键点击
  6. 所有任务
  7. 管理私钥
  8. 添加

如果您正在从Visual Studio运行代码,请尝试以管理员的身份运行Visual Studio。修复了我的问题。

我遇到了同样的问题,发现 这个答案 为我工作正常。钥匙是3072。 这个链接 提供有关“ 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

System.NET.WebException:该请求被中止:无法创建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.SecurityProtocol = SecurityProtocolType.Tls12;

顶级答案 对于大多数人来说可能就足够了。但是,在某些情况下,即使强迫TLS 1.2,您也可以继续获得“无法创建SSL/TLS安全频道”错误。如果是这样,您可能需要咨询 这篇有用的文章 有关其他故障排除步骤。总结:独立于TLS/SSL版本问题,客户端和服务器必须就“密码套件”达成协议。在SSL连接的“握手”阶段期间,客户端将列出其支持的密码套件,以供服务器符合其自己的列表。但是在某些Windows机器上,某些常见的密码插图可能已被禁用(似乎是由于限制攻击表面的良好尝试),从而减少了客户端和服务器在密码套件上达成共识的可能性。如果他们不能同意,那么您可能会在事件查看器中看到“致命警报代码40”,并且在.NET程序中“无法创建SSL/TLS安全频道”。

上述文章说明了如何列出机器所有潜在支持的密码套件,并通过Windows注册表启用其他密码套件。要帮助检查客户端启用哪些密码套件,请尝试访问 此诊断页 在MSIE。 (使用System.NET跟踪可能会给出更确定的结果。)要检查服务器支持哪些密码套件,请尝试 这个在线工具 (假设服务器是可以访问的)。不用说 注册表必须谨慎进行, ,尤其是涉及网络的地方。 (您的计算机是远程托管VM吗?如果您要中断网络,是否可以访问VM?)

在我公司的情况下,我们通过注册表编辑启用了其他几个“ ECDHE_ECDSA”套件,以解决直接问题并防止未来的问题。但是,如果您不能(或不会)编辑注册表,那么就会想到许多解决方法(不一定很漂亮)。例如:您的.NET程序可以将其SSL流量委派给单独的Python程序(该程序本身可能起作用,其原因是Chrome请求可能会在MSIE请求失败的情况下成功。

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

如何在证书商店中的证书中访问ASP.NET对私钥的访问?

就我而言,当Windows服务试图连接到Web服务时,我遇到了这个问题。在Windows事件中查看最终我找到了一个错误代码。

事件ID 36888(Schannel)被提高:

The following fatal alert was generated: 40. The internal error state is 808.

最后,它与Windows Hotfix有关。就我而言:KB3172605和KB3177186

VMware论坛中提出的解决方案是在Windows中添加了注册表条目。添加以下注册表后,一切都很好。

hkey_local_machine system currentcontrolset control securityProviders schannel keyexchangealgorithms diffie-hellman

“ clientminkeybitlength” = dword:00000200

显然,它与客户端的HTTPS握手中缺少值有关。

列出您的Windows Hotfix:

wmic qfe list

解决方案线程:

https://communities.vmware.com/message/2604912#2604912

希望有帮助。

这些答案对我不起作用。

这就是有效的方法:

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

   var certificate = new X509Certificate2(bytes, pass);

我这样做了:

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

注意 X509KeyStorageFlags.Exportable !!

我没有更改其余的代码( 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...
}

实际上,我什至不确定前两行是否需要...

这个问题可以有很多答案,因为这是关于一条通用错误消息。我们在一些服务器上遇到了这个问题,但没有开发机器。拔出大部分头发后,我们发现这是一个Microsoft错误。

https://support.microsoft.com/en-us/help/4458166/applications-applications-that-rely-on-tls-tls-tls-tls-1-2-strong-ectrong-ectrong-ectryption-experience-connect

从本质上讲,MS假设您需要更弱的加密,但是将操作系统修补仅允许TLS 1.2,因此您会收到可怕的“请求中止:无法创建SSL/TLS Secure Channel”。

有三个修复程序。

1)用正确更新修补操作系统: http://www.catalog.update.microsoft.com/search.aspx?q=kb44458166

2)将设置添加到您的app.config/web.config文件中。

3)添加另一个答案中已经提到的注册表设置。

所有这些都在我发布的知识库文章中提到。

您可以尝试安装演示证书(某些SSL提供商免费提供一个月),以确保问题是否与证书有效性有关。

只要这是一个相对“实时”链接,我认为我会添加一个新选项。这种可能性是,由于贵宾犬攻击的问题,该服务不再支持SSL 3.0。请查看有关此的Google语句。我一次遇到了几个Web服务的问题,并意识到必须发生一些事情。我切换到TLS 1.2,一切都恢复了正常。

http://googleonlinesecurity.blogspot.com/2014/10/this-poodle-bites-exploiting-ssl-30.html

这仅在一个站点上就对我发生了,事实证明它只有RC4密码可用。为了使服务器硬化,我已经禁用了RC4密码,一旦我重新启用了该问题,就解决了该问题。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top