You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

BouncyCastle .NET自定义TlsClient:Android可用Windows连接失败

解决Windows平台.NET应用连接使用TLS_ECDH_anon_WITH_AES_256_CBC_SHA套件的Java服务问题

我太懂这种两难的处境了——老旧的匿名加密套件因为安全风险被各大平台默认封杀,但依赖的服务又没法升级替换,只能想办法绕过去。之前你在Xamarin Android上靠Bouncy Castle搞定了,现在Windows平台的.NET应用卡壳很正常,下面给你两种经过验证的解决思路:


思路一:直接配置.NET启用目标加密套件(适用于.NET Core 3.0+/NET 5+)

Windows平台的.NET默认不会加载匿名ECDH类的加密套件,但我们可以通过代码手动指定要启用的套件,绕过系统默认限制。

代码示例

using System.Net.Security;
using System.Net.Sockets;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;

// 先建立基础TCP连接
var tcpClient = new TcpClient("你的Java服务地址", 443);
var networkStream = tcpClient.GetStream();

// 初始化SSL流,指定自定义认证逻辑
var sslStream = new SslStream(networkStream, false, ValidateAnonymousServerCert);

// 配置SSL认证选项,明确指定目标加密套件
var authOptions = new SslClientAuthenticationOptions
{
    TargetHost = "你的Java服务地址",
    EnabledSslProtocols = SslProtocols.Tls12, // TLS_ECDH_anon_WITH_AES_256_CBC_SHA属于TLS 1.2
    // 直接指定要使用的加密套件
    CipherSuitesPolicy = new CipherSuitesPolicy(new[]
    {
        CipherSuite.TLS_ECDH_anon_WITH_AES_256_CBC_SHA
    })
};

try
{
    // 发起TLS握手
    await sslStream.AuthenticateAsClientAsync(authOptions);
    Console.WriteLine("TLS握手成功!");
    
    // 这里可以开始通过sslStream进行读写通信
}
catch (Exception ex)
{
    Console.WriteLine($"握手失败:{ex.Message}");
}

// 匿名加密套件不需要验证服务器证书,直接返回true即可
bool ValidateAnonymousServerCert(object sender, X509Certificate? cert, X509Chain? chain, SslPolicyErrors errors)
{
    return true;
}

注意事项

  • 这个方案只适用于.NET Core 3.0及以上版本,或者.NET 5+;如果是.NET Framework,CipherSuitesPolicy不支持,建议直接用下面的Bouncy Castle方案。
  • 匿名套件没有身份验证,务必只在可信的内部网络环境中使用,避免中间人攻击风险。

思路二:用Bouncy Castle实现独立TLS客户端(通用所有.NET版本)

这就是你之前Xamarin Android用的思路——借助Bouncy Castle自带的完整TLS实现,完全脱离系统默认的加密套件限制,兼容性最好。

步骤1:安装Bouncy Castle NuGet包

在NuGet包管理器中搜索并安装 BouncyCastle.Crypto,或者通过Package Manager控制台执行:

Install-Package BouncyCastle.Crypto

步骤2:编写Bouncy Castle TLS客户端代码

using Org.BouncyCastle.Crypto.Tls;
using System.IO;
using System.Net.Sockets;

// 建立TCP连接
var tcpClient = new TcpClient("你的Java服务地址", 443);
var networkStream = tcpClient.GetStream();

// 自定义TLS客户端,指定目标加密套件
var tlsClient = new DefaultTlsClient()
{
    // 只保留我们需要的加密套件
    CipherSuites = new int[] { CipherSuite.TLS_ECDH_anon_WITH_AES_256_CBC_SHA }
};

// 创建Bouncy Castle的TLS流,跳过证书验证(匿名套件不需要)
var tlsStream = new TlsClientStream(networkStream, tlsClient, new TlsNoVerifyer());

try
{
    // 发起TLS握手
    tlsStream.AuthenticateAsClient("你的Java服务地址");
    Console.WriteLine("TLS握手成功!");
    
    // 示例:发送数据
    var sendBuffer = System.Text.Encoding.UTF8.GetBytes("测试数据");
    tlsStream.Write(sendBuffer, 0, sendBuffer.Length);
    tlsStream.Flush();
    
    // 示例:接收数据
    var receiveBuffer = new byte[1024];
    var bytesRead = tlsStream.Read(receiveBuffer, 0, receiveBuffer.Length);
    var response = System.Text.Encoding.UTF8.GetString(receiveBuffer, 0, bytesRead);
    Console.WriteLine($"收到响应:{response}");
}
catch (Exception ex)
{
    Console.WriteLine($"握手失败:{ex.Message}");
}
finally
{
    tlsStream?.Close();
    tcpClient?.Close();
}

// 自定义证书验证器,匿名套件直接返回通过
public class TlsNoVerifyer : ICertificateVerifyer
{
    public bool VerifyCertificate(byte[][] certChain, string targetHost)
    {
        return true;
    }
}

优势

  • 兼容所有.NET版本(包括.NET Framework、.NET Core、.NET 5+)。
  • 完全不受系统加密套件配置的限制,和你之前Xamarin的实现逻辑一致,迁移成本低。

内容的提问来源于stack exchange,提问作者wobuntu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 10:22:17