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

716

由于以下错误信息,我们无法使用WebRequest连接到HTTPS服务器:

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。这会改变什么吗?


4
也请查看这个链接 https://dev59.com/I3I-5IYBdhLWcg3w8dYQ - Oskar Kjellin
135
到了2018年,这个问题已经被查看了308,056次,但仍然没有适当的解决方法!!我会随机遇到这个问题,这里或其他线程提到的任何修复措施都不能解决我的问题。 - Nigel Fds
7
@NigelFds 错误The request was aborted: Could not create SSL/TLS secure channel是一个非常通用的错误。它基本上表示“由于许多可能的原因之一,SSL/TLS/HTTPS连接初始化失败”。因此,如果您在特定情况下经常遇到这个错误,最好的选择是提出一个具体的问题,并提供有关该情况的具体细节。同时,检查事件查看器以获取更多信息。另外,启用一些.NET客户端调试以获取更多详细信息(例如服务器证书是否不受信任?是否存在密码匹配问题?SSL/TLS协议版本不匹配等)。 - MarnixKlooster ReinstateMonica
6
@MarnixKlooster,我已经检查了所有内容,证书不可能是问题,因为如果我重试它,它就可以工作。我怀疑如果我在 SO 上提出这个问题,没有人会标记它为重复或其他什么。 - Nigel Fds
5
使用4.5.2几乎肯定是问题的主要原因。运行时确定安全协议的默认设置,而4.5.x只启用了SSL 3.0和TLS 1.0,这意味着如果您的应用程序调用了一个已禁用TLS 1.0的API,它将无法工作。尝试使用更高版本的.NET Framework,最好是4.7或更高版本。请参见我的答案获取更多详细信息,特别是如果您的应用程序是ASP.NET站点。 - JLRishe
显示剩余14条评论
51个回答

18
原始答案中缺少了一些东西。我添加了一些代码,使其更加健壮可靠。
ServicePointManager.Expect100Continue = true;
ServicePointManager.DefaultConnectionLimit = 9999;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 | SecurityProtocolType.Ssl3;

10
我不建议添加SSL3协议。 - Peter de Bruijn
1
SSL3存在一个严重的安全问题,称为“Poodle”。 - Peter de Bruijn
@PeterdeBruijn "Tls和Tls11"已经过时了吗? - Kiquenet
1
@Kiquenet - 是的。截至2018年6月,PCI(支付卡行业)将不允许低于TLS1.2的协议。(最初计划在06/2017实施,但推迟了一年) - GlennG
SSL/TLS家族中有五种协议:SSL v2、SSL v3、TLS v1.0、TLS v1.1和TLS v1.2:https://github.com/ssllabs/research/wiki/SSL-and-TLS-Deployment-Best-Practices SSL v2不安全,SSL v3在与HTTP一起使用时不安全(POODLE攻击),TLS v1.0、TLS v1.1已过时 唯一有效的选项是 ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 - Kiquenet

16
在调用HTTPS URL(适用于.NET Framework 4.5)之前,请尝试添加以下行:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

16
得票最高的答案 对大多数人来说可能已经足够了。但是在某些情况下,即使强制使用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请求可能会失败)。

8
当我将鼠标悬停在“这篇有用的文章”链接上,想看看它可能是什么内容时,突然发现它是指向我的博客上一篇文章的链接,这种感觉真是太棒了! - Jon Schneider

15

这个方法在MVC Web客户端对我有效

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;
    }
}

6
覆盖 ServerCertificateValidationCallback 会引入新的安全漏洞吗? - user1021364
这对我来说就像JET一样有效。 - mahdi moghimi
@user1021364,它能够入侵我的系统吗?由于我们没有实际的网络系统。 - Arun Prasad E S

15

"请求被中止:无法创建 SSL/TLS 安全通道" 异常可能会在服务器返回 HTTP 401 未经授权 响应到 HTTP 请求时发生。

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

一旦配置好日志记录,运行应用程序并重现错误,然后查看日志输出中是否有类似于以下行的内容:

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

在我的情况下,我未能设置服务器期望的特定Cookie,导致服务器以401错误响应该请求,从而导致“无法创建SSL / TLS安全通道”异常。


1
我的任务调度器每天执行(不包括周末)。我经常遇到同样的错误,但有时候(2个月内出现2次错误)。当我遇到这个错误时,几分钟后我手动再试一次,一切都正常。 - Kiquenet

14

这样做对我有帮助:

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

14
另一个可能性是盒子中证书的导入不正确。一定要选择被圈起来的复选框。最初我没有这样做,因此代码要么超时,要么抛出与找不到私钥相同的异常。 certificate importation dialog

客户不断地需要重新安装证书才能使用客户端程序。一遍又一遍地,他们必须在使用该程序之前重新安装证书。我希望这个答案可以解决这个问题。 - Pangamma

13

我遇到了这个问题,因为我的web.config文件里有:

<httpRuntime targetFramework="4.5.2" />

而不是:

<httpRuntime targetFramework="4.6.1" />

问题已经解决。在客户端应用程序的webconfig文件中,我设置了httpRuntime为4.5。将其更改为4.7.2。我之前已经从4.5升级到4.7.2,但不确定为什么没有更新。无论如何,这帮了我一个大忙。 - Jashvita

12

在我的情况下,运行该应用程序的服务帐户没有访问私钥的权限。一旦我授予了这个权限,错误就消失了。

  1. mmc
  2. 证书
  3. 展开到个人
  4. 选择证书
  5. 右键单击
  6. 所有任务
  7. 管理私钥
  8. 添加服务账户用户

1
你能否通过添加截图等方式详细说明完整的过程来扩展答案?在第8步中你添加了什么? - Ash K

10

在我的情况下,这个异常的根源是代码中某个时刻调用了以下内容:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;

这真的很糟糕。它不仅指示.NET使用不安全的协议,而且会影响应用程序域内之后进行的每个新WebClient(以及类似的)请求。(请注意,您ASP.NET应用程序中的传入Web请求不受影响,但是新的WebClient请求(例如与外部Web服务通信)则会受到影响)。

在我的情况下,实际上并不需要它,所以我可以删除这个语句,然后所有其他的Web请求再次正常工作。根据我在其他地方阅读的内容,我学到了一些东西:

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

2
与您的一般经验相反,我要补充一点,即在必须设置为TLS 1.2而不是让默认运行时,有一个例外。如果您使用的框架早于.NET 4.6,并且在服务器上禁用了不安全的协议(SSL或TLS 1.0 / 1.1),则除非将程序强制转换为TLS 1.2,否则无法发出请求。 - Paul

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接