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


当前回答

这一个是为我工作在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;
    }
}

其他回答

如果服务器对HTTP请求返回HTTP 401未授权响应,则会出现“请求已终止:无法创建SSL/TLS安全通道”异常。

您可以通过打开跟踪级系统来确定是否发生这种情况。Net日志记录用于客户端应用程序,如本回答中所述。

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

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

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

另一种可能是正在执行的代码没有所需的权限。

在我的例子中,我在使用Visual Studio调试器测试对web服务的调用时得到了这个错误。Visual Studio没有以管理员身份运行,这导致了此异常。

注意:这里投票最多的几个答案建议设置ServicePointManager。安全协议,但微软明确建议不要这样做。下面,我将讨论此问题的典型原因以及解决该问题的最佳实践。

这个问题的最大原因之一是活动的。net框架版本。. net框架运行时版本会影响默认启用的安全协议。

在ASP。NET站点,框架运行时版本通常在web.config中指定。(见下文) 在其他应用程序中,运行时版本通常是构建项目的版本,而不管它是否运行在具有更新的. net版本的机器上。

似乎没有任何权威的文档说明它在不同版本中是如何具体工作的,但似乎默认值或多或少是这样确定的:

Framework Version Default Protocols
4.5 and earlier SSL 3.0, TLS 1.0
4.6.x TLS 1.0, 1.1, 1.2, 1.3
4.7+ System (OS) Defaults

对于较旧的版本,根据系统上安装的. net运行时的不同,您的里程可能会有所不同。例如,可能会出现这样的情况,您正在使用一个非常旧的框架,不支持TLS 1.0,或者使用4.6。不支持TLS 1.3。

微软的文档强烈建议使用4.7+和系统默认值:

我们建议您: 在你的应用程序上瞄准。net Framework 4.7或更高版本。在你的WCF应用中瞄准。net Framework 4.7.1或更高版本。 不指定TLS版本。配置代码,让操作系统决定TLS版本。 执行彻底的代码审计,以验证您没有指定TLS或SSL版本。

ASP。NET站点:检查<httpRuntime>元素中的targetFramework版本,因为这个(当出现时)决定了你的站点实际使用的运行时:

<httpRuntime targetFramework="4.5" />

好:

<httpRuntime targetFramework="4.7" />

在。net 4.5中,这个问题的解决方案是

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

如果你没有。net 4.5,那就使用

ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;

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

mmc 证书 扩展到个人 选择证书 右击 所有任务 管理私钥 添加业务帐户用户