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


当前回答

对于SOAP/WCF用户,当服务器拒绝您的WS-Security配置时,也会发生此错误。客户端接收到的错误信息非常模糊,但是服务器管理员可能能够确定原因。

UsernameToken配置文件下有一个这样的例子,其中消息被<wsu:Created> time视为过期,不是有效的ISO 8601 datetime,原因可能是格式错误、不是UTC或服务器时间不匹配。

<wsse:UsernameToken wsu:Id="Example-1">
   <wsse:Username> ... </wsse:Username>
   <wsse:Password Type="..."> ... </wsse:Password>
   <wsse:Nonce EncodingType="..."> ... </wsse:Nonce>
   <wsu:Created>2021-01-31T19:00:00.0000000Z</wsu:Created>
</wsse:UsernameToken>

其他回答

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

事件ID 36888(通道)被引发:

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

最后,它与Windows热修复有关。在我的例子中是KB3172605和KB3177186

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

[HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ \控制SecurityProviders \ SCHANNEL \ KeyExchangeAlgorithms \ diffie - hellman)

“ClientMinKeyBitLength”= dword: 00000200

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

列出你的Windows HotFix:

wmic qfe list

解决方案线程:

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

希望对大家有所帮助。

The top-voted answer will probably be enough for most people. However, in some circumstances, you could continue getting a "Could not create SSL/TLS secure channel" error even after forcing TLS 1.2. If so, you may want to consult this helpful article for additional troubleshooting steps. To summarize: independent of the TLS/SSL version issue, the client and server must agree on a "cipher suite." During the "handshake" phase of the SSL connection, the client will list its supported cipher-suites for the server to check against its own list. But on some Windows machines, certain common cipher-suites may have been disabled (seemingly due to well-intentioned attempts to limit attack surface), decreasing the possibility of the client & server agreeing on a cipher suite. If they cannot agree, then you may see "fatal alert code 40" in the event viewer and "Could not create SSL/TLS secure channel" in your .NET program.

The aforementioned article explains how to list all of a machine's potentially-supported cipher suites and enable additional cipher suites through the Windows Registry. To help check which cipher suites are enabled on the client, try visiting this diagnostic page in MSIE. (Using System.Net tracing may give more definitive results.) To check which cipher suites are supported by the server, try this online tool (assuming that the server is Internet-accessible). It should go without saying that Registry edits must be done with caution, especially where networking is involved. (Is your machine a remote-hosted VM? If you were to break networking, would the VM be accessible at all?)

在我公司的案例中,我们通过注册表编辑启用了几个额外的“ECDHE_ECDSA”套件,以修复当前的问题并防范未来的问题。但是如果你不能(或不愿意)编辑注册表,那么很多变通办法(不一定漂亮)就会出现在你的脑海中。例如:你的. net程序可以将它的SSL通信委托给一个单独的Python程序(它本身也可以工作,因为同样的原因,Chrome请求可能成功,而MSIE请求在受影响的机器上失败)。

我也有同样的问题,发现这个答案对我很有效。密码是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

我终于找到了答案(我没有注明我的来源,但它来自一次搜索);

虽然代码在Windows XP中工作,但在Windows 7中,你必须在开头添加这个:

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

现在,它工作得很完美。


齿顶高

Robin French提到过;如果你在配置PayPal时遇到了这个问题,请注意从2018年12月3日开始他们将不支持SSL3。您需要使用TLS。这是关于它的Paypal页面。

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