代码之家  ›  专栏  ›  技术社区  ›  Simon Dugré Metin Atalay

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

  •  267
  • Simon Dugré Metin Atalay  · 技术社区  · 16 年前

    无法使用连接到HTTPS服务器 WebRequest 由于此错误消息:

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

    我们知道服务器没有使用路径的有效HTTPS证书,但为了绕过此问题,我们使用从另一个stackoverflow post获取的以下代码:

    private void Somewhere() {
        ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(AlwaysGoodCertificate);
    }
    
    private static bool AlwaysGoodCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors policyErrors) {
       return true;
    }
    

    问题是服务器永远不会验证证书,并由于上述错误而失败。有人知道我该怎么做吗?


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

    33 回复  |  直到 7 年前
        1
  •  395
  •   Simon Dugré Metin Atalay    7 年前

    我终于找到了答案(我没有注意到我的来源,但它是通过搜索得到的);

    当代码在Windows XP和Windows 7中工作时,必须在开头添加:

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

    现在,它工作得很好。


    补遗

    如罗宾法语所提到的,如果你在配置PayPal时遇到这个问题,请注意,他们不会支持SSL3从十二月开始,第三2018。您需要使用TLS。这里是 Paypal page 关于它。

        2
  •  74
  •   Andrej Z    8 年前

    在.NET 4.5中,解决这个问题的方法是

    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
    

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

    ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;
    
        3
  •  33
  •   hogarth45    7 年前

    请确保在创建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;
    
        4
  •  29
  •   Community Mohan Dere    9 年前

    您遇到的问题是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

        5
  •  24
  •   Remus Rusanu    16 年前

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

    最好的解决方案是使用Schannel故障排除工具集。Schannel是负责SSL和TLS的SSPI提供者,您的客户机将使用它进行握手。看一看 TLS/SSL Tools and Settings .

    也看到 How to enable Schannel event logging .

        6
  •  24
  •   Bryan Legend    11 年前

    我试着打这个问题 https://ct.mob0.com/Styles/Fun.png 这是CloudFlare在其cdn上发布的一张图片,它支持spdy和奇怪的重定向ssl证书等疯狂的东西。

    我没有在Simons的答案中指定ssl3,而是可以通过如下方式转到tls12来修复它:

    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
    new WebClient().DownloadData("https://ct.mob0.com/Styles/Fun.png");
    
        7
  •  16
  •   Nick Gotch    11 年前

    经过长时间的处理,我发现运行客户端服务的ASP.NET帐户没有访问证书的权限。我通过进入运行Web应用程序的IIS应用程序池、进入高级设置并将标识更改为 LocalSystem 从帐户 NetworkService .

    更好的解决方案是让证书使用默认值 网路服务 但是这对于快速的功能测试是有效的。

        8
  •  14
  •   SpoiledTechie.com    10 年前

    一些原始答案没有的东西。我又添加了一些代码,使之防弹。

    ServicePointManager.Expect100Continue = true;
            ServicePointManager.DefaultConnectionLimit = 9999;
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 | SecurityProtocolType.Ssl3;
    
        9
  •  13
  •   Sherlock    14 年前

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

    选中“环绕”复选框。最初我没有这样做,所以代码要么超时,要么抛出的异常和无法定位私钥的异常相同。

    certificate importation dialog

        10
  •  9
  •   Community Mohan Dere    9 年前

    如果服务器返回一个 HTTP 401未经授权 对HTTP请求的响应。

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

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

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

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

        11
  •  8
  •   Arun Prasad E S    8 年前

    这个在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;
            }
        }
    
        12
  •  7
  •   TCC    12 年前

    正如你所知道的,这有很多可能发生的原因。我想我会加上我遇到的原因…

    如果您设置 WebRequest.Timeout 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 ...
    
        13
  •  7
  •   Community Mohan Dere    9 年前

    在我的例子中,这个异常的根源是在代码中的某个时刻调用了以下代码:

    ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
    

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

    在我的例子中,实际上并不需要它,所以我可以删除这个语句,然后我的所有其他Web请求就可以再次正常工作了。根据我在别处的阅读,我学到了一些东西:

    • 这是AppDomain中的全局设置,如果您有并发活动,则无法将其可靠地设置为一个值,执行操作,然后将其设置回。另一个操作可能在该小窗口期间发生并受到影响。
    • 正确的设置是将其保留为默认值。这使得.NET可以继续使用最安全的默认值,随着时间的推移和您升级框架。将其设置为tls12(在本文撰写时是最安全的)将起作用。 现在 但5年后可能会引发一些神秘的问题。
    • 如果您真的需要设置一个值,您应该考虑在单独的专用应用程序或AppDomain中进行设置,并找到一种方法在它和您的主池之间进行对话。因为它是一个单一的全局值,所以在繁忙的应用程序池中管理它只会带来麻烦。这个答案: https://stackoverflow.com/a/26754917/7656 通过自定义代理提供可能的解决方案。(注意,我没有亲自实施。)
        14
  •  6
  •   aghost    10 年前

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

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

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

    奇怪,没有其他错误信息,但是 “请求已中止:无法创建SSL/TLS安全通道。” 出现此错误

        15
  •  6
  •   Jon Schneider Stefan    10 年前

    另一个可能的原因是 The request was aborted: Could not create SSL/TLS secure channel 错误是 客户端PC配置的密码套件值与服务器配置为愿意和能够接受的值不匹配 . 在这种情况下,当客户端发送其在初始SSL握手/协商“client hello”消息中能够接受的密码套件值列表时,服务器会发现所提供的任何值都不可接受,并可能返回“alert”响应,而不是继续执行SSL握手的“server hello”步骤。

    为了调查这种可能性,您可以下载 Microsoft Message Analyzer ,并使用它在尝试建立到服务器的HTTPS连接(在您的C应用程序中)失败时发生的SSL协商上运行跟踪。

    如果您能够从另一个环境(例如您提到的Windows XP计算机)成功建立HTTPS连接,或者在不使用操作系统密码套件设置(如Chrome或Firefox)的非Microsoft浏览器中点击HTTPS URL,则在该环境中运行另一个消息分析器跟踪以捕获发生的情况。当SSL协商成功时。

    希望,您将看到两个客户机hello消息之间的一些区别,这将使您能够准确地确定失败的SSL协商导致它失败的原因。然后,您应该能够对Windows进行配置更改,以使其成功。 IISCrypto 这是一个很好的工具来使用(即使对于客户机PC,尽管有“IIS”的名称)。

    以下两个Windows注册表项控制PC将使用的密码套件值:

    • 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

        16
  •  5
  •   cnom Evert    9 年前

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

    这可以设置为:

    < Buff行情>

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

    < /块引用>

    将设置向下滚动到“安全”并在两者之间进行选择

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

    这可以设置在:

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

    将设置向下滚动到“安全”并在其中进行选择

    • 使用SSL 2
    • 使用SSL 3
    • 使用TLS 1
    • 使用TLS 1.1
    • 使用TLS 1.2

    enter image description here

        17
  •  4
  •   Terje Solem    9 年前

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

    <httpRuntime targetFramework="4.5.2" />
    

    而不是:

    <httpRuntime targetFramework="4.6.1" />
    
        18
  •  3
  •   Dinesh Rajan    8 年前

    在我的例子中,运行应用程序的服务帐户没有访问私钥的权限。一旦我给予许可,错误就消失了。

    1. 丝裂霉素
    2. 证书
    3. 扩展到个人
    4. 选择证书
    5. 右击
    6. 所有任务
    7. 管理私钥
    8. 添加
        19
  •  3
  •   Stephen Rauch Afsar Ali    8 年前

    我也遇到了同样的问题 this answer 为我工作得很好。钥匙是3072。 This link 提供“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
    
        20
  •  3
  •   capdragon    8 年前

    System.net.WebException:请求被中止:无法创建 SSL/TLS安全通道。

    在我们的例子中,我们使用了一个软件供应商,所以我们没有权限修改.NET代码。显然.NET 4不会使用TLS v 1.2,除非有更改。

    我们的修复方法是将schosestrongcrypto项添加到注册表中。您可以将下面的代码复制/粘贴到扩展名为.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
    
        21
  •  2
  •   Community Mohan Dere    9 年前

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

    How to give ASP.NET access to a private key in a certificate in the certificate store?

        22
  •  2
  •   handles    8 年前

    如果正在从Visual Studio运行代码,请尝试以管理员身份运行Visual Studio。帮我解决了这个问题。

        23
  •  2
  •   Michael Silver    7 年前

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

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

    本质上,MS假定您想要更弱的加密,但操作系统的补丁只允许TLS 1.2,因此您收到了可怕的“请求被中止:无法创建SSL/TLS安全通道”。

    有三种方法。

    1)用正确的更新补丁操作系统: http://www.catalog.update.microsoft.com/Search.aspx?q=kb4458166

    2)在app.config/web.config文件中添加设置。

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

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

        24
  •  2
  •   Muhammad Awais    7 年前

    试试这个:

    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
    
        25
  •  1
  •   twk    16 年前

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

        26
  •  1
  •   Jeff Lehmer    11 年前

    只要这是一个相对“实时”的链接,我想我会添加一个新的选项。这种可能性是由于poodle攻击的问题,服务不再支持ssl 3.0。看看谷歌关于这个的声明。我同时遇到了几个Web服务的这个问题,并且意识到必须要发生一些事情。我换上了1.2,一切又恢复了正常。

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

        27
  •  1
  •   Mark Reid    11 年前

    我只在一个站点上发生了这种情况,结果发现它只有RC4密码可用。在之前加强服务器的工作中,我禁用了RC4密码,一旦重新启用,问题就解决了。

        28
  •  1
  •   Carl Prothman    10 年前

    除上述答案外,请确保已将CER证书而不是pfx文件导入本地计算机存储。两个文件同时存在时的常见错误。

        29
  •  1
  •   Hernán Velásquez García    8 年前

    在我的例子中,当一个Windows服务试图连接到一个Web服务时,我遇到了这个问题。在Windows事件中,我终于找到了一个错误代码。

    引发事件ID 36888(Schannel):

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

    最后,它与Windows修补程序相关。在我的例子中:KB372650和KB377186

    在vmware论坛中提出的解决方案是在Windows中添加一个注册表项。添加以下注册表后,一切正常。

    [hkey_local_machine\system\currentcontrolset\control\securityproviders\schannel\keyexchangealgorithms\diffie-hellman]

    “clientMinKeyBitLength”=dword:00000200

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

    列出Windows修补程序:

    wmic qfe list
    

    解决方案线程:

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

    希望有帮助。

        30
  •  1
  •   jayasurya_j    8 年前

    此为我修复,将网络服务添加到权限。 右键单击“证书”>“所有任务”>“管理私钥”>“添加”>“网络服务”