C#调用WebClient时无法创建SSL/TLS安全通道报错怎么解决
问题排查与解决方法
核心原因定位
你遇到的SSL/TLS通道创建失败,绝大多数情况是配置顺序、运行环境支持度、协议匹配的问题,按以下步骤逐一排查即可:
排查解决步骤
- 调整ServicePointManager配置顺序
ServicePointManager的配置必须在所有HTTP请求相关对象实例化之前执行,你当前代码先创建了WebClient实例再修改配置,会导致配置不生效,直接把三行配置代码移到new WebClient()之前即可。 - 扩展支持的TLS协议版本
不要仅固定TLS1.2,当前多数站点已支持TLS1.3,部分站点会强制要求更高版本协议,修改配置为同时支持TLS1.2和TLS1.3:
// .NET Framework >=4.8 可直接用枚举 ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls13; // .NET Framework <4.8 版本没有Tls13枚举,用数值代替 ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072 | (SecurityProtocolType)12288;
- 检查运行环境的TLS支持
- 如果你使用的是.NET Framework 4.5及更低版本,默认不支持TLS1.2,需要升级框架版本到4.5.2以上,推荐升级到4.8。
- 如果程序运行在Windows 7/Windows Server 2008 R2系统上,系统默认未开启TLS1.2客户端支持,需要修改注册表开启:
定位到路径HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client,新建两个DWORD值:DisabledByDefault设为0,Enabled设为1,修改后重启系统生效。
- 替换过时的WebClient为HttpClient
WebClient在.NET Core/.NET 5+中已被标记为过时,内部实现依赖全局的ServicePointManager配置,灵活性差,推荐用HttpClient代替,配置更可控:
// HttpClient建议全局单例使用,不要每次请求重复实例化 var handler = new HttpClientHandler { // 仅当前客户端实例忽略证书验证,不会影响全局请求 ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true, SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls13 }; using var client = new HttpClient(handler); client.DefaultRequestHeaders.Referrer = new Uri("https://d.easytrader.emofid.com/"); client.DefaultRequestHeaders.Accept.ParseAdd("application/json, text/plain, */*"); client.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"); client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authorization); // 如authorization已带前缀可直接赋值 byte[] DataResive = await client.GetByteArrayAsync("https://cl3.emofid.com/easy/api/account/checkuser");
- 排查网络链路问题
先在当前运行环境的浏览器中直接访问目标接口地址,确认可以正常访问,无防火墙、代理拦截,无证书风险提示,排除网络层面的握手拦截问题。
修正后的WebClient代码示例
// 先配置ServicePointManager,再实例化WebClient ServicePointManager.Expect100Continue = true; ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls13; ServicePointManager.ServerCertificateValidationCallback = ((sender, certificate, chain, sslPolicyErrors) => true); WebClient webClient = new WebClient(); webClient.Headers[HttpRequestHeader.Referer] = "https://d.easytrader.emofid.com/"; webClient.Headers.Add(HttpRequestHeader.Accept, "application/json, text/plain, */*"); webClient.Headers.Add(HttpRequestHeader.UserAgent, "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"); webClient.Headers.Add(HttpRequestHeader.ContentType, "application/json"); webClient.Headers.Add(HttpRequestHeader.Authorization, authorization); byte[] DataResive = await webClient.DownloadDataTaskAsync("https://cl3.emofid.com/easy/api/account/checkuser");
内容的提问来源于stack exchange,提问作者Mohamad Ghanbari
相关产品推荐
相关产品推荐

