身份验证失败,因为远程方已关闭传输流

Posted

技术标签:

【中文标题】身份验证失败,因为远程方已关闭传输流【英文标题】:Authentication failed because remote party has closed the transport stream 【发布时间】:2015-08-20 06:54:54 【问题描述】:

我正在开发一个 TCP 客户端来连接 OpenSSL 服务器和证书认证。我使用了服务器团队共享的 .crt 和 .key 文件。这些证书由 OpenSSL 命令生成。

我正在使用SslStream 对象通过传递服务器IPSslProtocols.Ssl3X509CertificateCollection 调用SslStream.AuthenticateAsClient 方法来验证Tcp 客户端。

我收到以下错误:

验证失败,因为对方已经关闭了传输流

【问题讨论】:

这似乎是 POODLE 后时代的一个问题:SslProtocols.Ssl3。也许你应该试试SslProtocols.Tls。在 .Net 4.5 及更高版本中,您还可以使用Tls11Tls12。见SslProtocols Enumeration。您可能还有其他问题。 另见Socket and Authentication failed because the remote party has closed the transport stream exception in WPF。 谢谢。我的问题是通过从证书和密码的物理路径附加证书而不是从 Windows 证书存储中搜索证书主题名称来解决的。 现在我可以从所有的 SslProtocols(SSL3、Tls1 和 Tls2)中得到结果了。感谢回复 @Odelu,你是如何解决这个问题的?在客户端还是服务器端? 【参考方案1】:

我建议不要将 SecurityProtocol 限制为 TLS 1.1。

推荐的解决方案是使用

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

另一个选项是添加以下注册表项:

Key: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319 
Value: SchUseStrongCrypto 

值得注意的是,.NET 4.6 默认会使用正确的协议,不需要任何一种解决方案。

【讨论】:

哇,你刚刚解决了我的问题——我尝试了各种各样的事情——然后在这里看到了框架上的注释。刚刚将其切换到 4.6.1(正在使用 4.5),希望问题出在框架可能使用了错误的安全协议 - 宾果游戏,我的连接没有被拒绝,我正在获取我的数据! 重要的是要说System.Net.ServicePointManager.SecurityProtocol = ...必须在创建请求之前执行。 目标框架版本更新到 4.6.1 救了我的命 :-) 我的框架设置为4.6.2。也许我不得不改用 TLS 解决方案 我正在使用 4.7.2 框架,我发送请求的站点也在使用 TLS 1.2,但它就像来自 10 的 6 个请求一样,我收到此错误。有什么想法吗?【参考方案2】:

如果您想使用旧版本的 .net,请创建自己的标志并进行转换。

    //
    // Summary:
    //     Specifies the security protocols that are supported by the Schannel security
    //     package.
    [Flags]
    private enum MySecurityProtocolType
    
        //
        // Summary:
        //     Specifies the Secure Socket Layer (SSL) 3.0 security protocol.
        Ssl3 = 48,
        //
        // Summary:
        //     Specifies the Transport Layer Security (TLS) 1.0 security protocol.
        Tls = 192,
        //
        // Summary:
        //     Specifies the Transport Layer Security (TLS) 1.1 security protocol.
        Tls11 = 768,
        //
        // Summary:
        //     Specifies the Transport Layer Security (TLS) 1.2 security protocol.
        Tls12 = 3072
    
    public Session()
    
        System.Net.ServicePointManager.SecurityProtocol = (SecurityProtocolType)(MySecurityProtocolType.Tls12 | MySecurityProtocolType.Tls11 | MySecurityProtocolType.Tls);
    

【讨论】:

你不必使用自己的类,可以直接将整数转换为SecurityProtocolType ServicePointManager.SecurityProtocol = (SecurityProtocolType) 48 | (SecurityProtocolType) 192 | (SecurityProtocolType) 768 | (SecurityProtocolType) 3072;【参考方案3】:

添加以下代码帮助我解决了这个问题。

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11;

【讨论】:

【参考方案4】:
using (var client = new HttpClient(handler))
            
                ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
                var response = await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, apiEndPoint)).ConfigureAwait(false);
                await response.Content.ReadAsStringAsync().ConfigureAwait(false);
            

这对我有用

【讨论】:

关键位是以下行:ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 |安全协议类型.Tls11 |安全协议类型.Tls;这个答案很好,因为它显示了该行在典型用例中的位置。【参考方案5】:

我在使用 ChargifyNET.dll 与 Chargify API 通信时遇到了相同的错误消息。将chargify.ProtocolType = SecurityProtocolType.Tls12; 添加到配置中解决了我的问题。

这里是完整的代码sn-p:

public ChargifyConnect GetChargifyConnect()

    var chargify = new ChargifyConnect();
    chargify.apiKey = ConfigurationManager.AppSettings["Chargify.apiKey"];
    chargify.Password = ConfigurationManager.AppSettings["Chargify.apiPassword"];
    chargify.URL = ConfigurationManager.AppSettings["Chargify.url"];

    // Without this an error will be thrown.
    chargify.ProtocolType = SecurityProtocolType.Tls12;

    return chargify;

【讨论】:

【参考方案6】:

对于 VB.NET,您可以在 Web 请求之前放置以下内容:

Const _Tls12 As SslProtocols = DirectCast(&HC00, SslProtocols)
Const Tls12 As SecurityProtocolType = DirectCast(_Tls12, SecurityProtocolType)
ServicePointManager.SecurityProtocol = Tls12

这解决了我在 .NET 3.5 上的安全问题。

【讨论】:

【参考方案7】:

当 Web 请求端点切换到仅接受 TLS1.2 请求的另一台服务器时,这发生在我身上。尝试了很多尝试,主要是在 *** 上发现的,比如

    注册表键, 已添加: System.Net.ServicePointManager.SecurityProtocol |= System.Net.SecurityProtocolType.Tls12;到 Global.ASX OnStart, 在 Web.config 中添加。 将 .Net 框架更新到 4.7.2 仍然遇到同样的异常。

收到的异常并没有解决我所面临的实际问题,也没有从服务运营商那里得到任何帮助。

为了解决这个问题,我必须添加一个新的密码套件 TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 我使用了来自 here 的 IIS Crypto 2.0 工具,如下所示。

【讨论】:

以上是关于身份验证失败,因为远程方已关闭传输流的主要内容,如果未能解决你的问题,请参考以下文章

HttpWebrequest 失败,内部异常身份验证失败,因为远程方已关闭传输流

身份验证失败,因为远程方已关闭传输流

C# 身份验证失败,因为远程方已关闭传输流

身份验证失败,因为远程方已关闭传输流 - 发送 smtp 错误

HTTP Get 请求错误“身份验证失败,因为远程方已关闭传输流。”

推送通知上的错误“身份验证失败,因为远程方已关闭传输流”