C#请求HTTPS地址的故障分析和TLS知识点总结
背景介绍
近期收到同事反馈,在C#程序中通过HTTPClient请求一个HTTPS的地址时,在本地开发环境和测试环境均能正常执行,而部署到生产环境后发生异常且稳定复现,异常提示为:【请求被中止: 未能创建 SSL/TLS 安全通道 】,而且在生产环境用浏览器访问是没问题的。
目标站点和运行环境介绍
- 目标站点SiteA(同事对接的站点):jc.ebopark.com
- 目标站点SiteB(对比站点):www.howsmyssl.com
- 生产环境服务器MA1:Windows Server 2016 Datacenter+.NET Framework 4.8,镜像来自Azure
- 测试环境服务器T1:Windows Server 2016 Datacenter+.NET Framework 4.8,镜像来自Azure
- 本地临时VMware虚拟机VM1:Windows Server 2016 Datacenter+.NET Framework 4.8,镜像来自微软官网
初步分析
自然的,根据异常信息先进行一圈Google(不用百度),基本都是在说ServicePointManager.SecurityProtocol的赋值,但是本次的程序中已经配置了全部协议。在了解了大概背景之后,基本断定该故障与源码本身的关系不大,仔细检查源码后也确实没有问题。大家也能看得出,很明显的环境不同导致的故障,那么宿主环境的差异就是我们优先要排查分析的线索。
这里要引入HTTPS的一些知识点
1、关于HTTP、HTTPS、TLS的关系:HTTPS连接是由HTTP协议与TLS协议共同完成。

2、建立HTTPS连接不仅需要Client与Server双方的TLS协议版本号兼容,还需要Cipher Suites(密码套件)兼容。关于什么是Cipher Suites可以自行查阅资料,本文不详细展开说明。Cipher Suites的样子如图所示:

进一步验证
有了以上理论支撑,下面就开始对本次案例的站点和运行环境进行一一分析;
首先,通过在线工具验证目标站点SiteA自身的HTTPS连接功能是否OK:

截图报告显示SiteA支持TLS1.2、TLS1.3协议,同时也可以看到对应的密码套件。说明该站点自身配置没问题,这也符合同事的测试结果。
根据前面提到的知识点,下一步就需要判断连接的Client端(即C#应用)所支持的协议和密码套件。先看在程序中配置的是支持TLS全协议:
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 |
SecurityProtocolType.Tls |
SecurityProtocolType.Tls11 |
SecurityProtocolType.Tls12 |
(SecurityProtocolType) 12288;
其次查看运行时部署的.NET Framework 4.8对TLS的兼容情况,如下图所示,环境对TLS1.2、TLS1.3均支持。

现在TLS协议看起来是兼容的,那么该如何查看C#应用所使用的密码套件?这里用到一个工具:IISCrypto.exe
生产环境服务器MA1的密码套件如下图所示。经过仔细对比,该OS没有与目标站点SiteA匹配的密码套件,因此无法建立连接,符合实际情况。

测试环境服务器T1的密码套件如下图所示。该OS中有2组和目标站点SiteA的TLS1.2密码套件匹配,因此可以建立链接,符合实际情况。

本地临时VMware虚拟机VM1的密码套件如下图所示,该OS中有多组和目标站点SiteA的TLS1.2密码套件匹配,因此可以建立链接,符合实际情况。

经过上述对比后,基本可以判定是由于生产环境的服务器密码套件与目标站点不匹配导致。
解决方案比较简单,使用IISCrypt工具把缺少的密码套件勾选,并择机重启服务器生效即可。
延伸1:如何创建TLS1.3协议的连接?
根据前面对几台服务器的密码套件的分析,兼容的密码套件都是最多是TLS1.2版本的,那是否真可以创建TLS1.3的连接呢?所幸我本地开发环境比较新,是Windows11,经过查看密码套件可以兼容TLS1.3:

使用工具在只选择TLS1.3协议的情况下,验证是可以成功请求的:

延申2:Edge浏览器所支持的密码套件自带的,独立于Windows。
下图是生产环境服务器MA1上的Edge浏览器的密码套件支持情况。

通过该浏览器直接请求目标站点SiteA,不仅可以请求成功而且还是走的TLS1.3协议。

总结
本文针对实际开发中遇到怪异现象,结合HTTPS的理论知识,透彻的分析了故障原因并最终解决。本文中还提到了几个实用的工具,可以更方便的查看相关细节。最后针对生产服务器镜像默认的密码套件问题,后续会继续与运维同事反馈并更新。
参考资料:
- 查看TLS在线工具:https://myssl.com/ssl.html
- IISCrypto官网:https://www.nartac.com/Products/IISCrypto/
- .NET Framework 中的传输层安全性 (TLS) 最佳做法:https://docs.microsoft.com/en-us/dotnet/framework/network-programming/tls
- 查看当前连接的tls信息-API版:https://www.howsmyssl.com/a/check
附:苹果推送服务API的TLS信息

C#请求HTTPS地址的故障分析和TLS知识点总结的更多相关文章
- java请求https地址如何绕过证书验证?
原文http://www.blogjava.net/hector/archive/2012/10/23/390073.html 第一种方法,适用于httpclient4.X 里边有get和post两种 ...
- 通过证书请求Https站点
前几天在做与平安银行对接接口,主要是给平安银行推送用户数据(申请贷款的用户),平安银行提供的是https的地址,请求https地址的时候还要发送证书,刚接到这个任务的时候一头雾水,百度上各种所搜,最后 ...
- [Delphi]实现使用TIdHttp控件向https地址Post请求[转]
开篇:公司之前一直使用http协议进行交互(比如登录等功能),但是经常被爆安全性不高,所以准备改用https协议.百度了一下资料,其实使用IdHttp控件实现https交互的帖子并不少,鉴于这次成功实 ...
- 彻底解决:请求被中止: 未能创建 SSL/TLS 安全通道
最近有个项目要调用客户用java写的带https的webservice,对方提供了证书文件 test.pfx,我这里调用方式如下: //webservice代理类 SvcService svc = n ...
- HttpWebRequest请求Https协议的WebApi
public static class RequestClient { /// <summary> /// 参数列表转为string /// </summary> /// &l ...
- C# 解决“请求被中止: 未能创建 SSL/TLS 安全通道”的问题
最近在开发项目的时候,使用爬虫抓取网络数据的时候,当请求Web数据时,碰到了“请求被中止: 未能创建 SSL/TLS 安全通道”的问题,尝试过很多网上的方法,例如添加证书等都没有用.最后在GitHub ...
- 带jsk证书,请求https接口
首先是三个返回的实体类 BaseVo.java package https2; import java.io.Serializable; import java.lang.reflect.Invoca ...
- .NET HttpWebRequest(请求被中止: 未能创建 SSL/TLS 安全通道)和(基础连接已经关闭: 发送时发生错误)问题查找解决
前言: 前段时间在对接第三方接口的时候发生了一个非常奇葩的问题,就是使用 .NET Framework 4.6 HttpWebRequest进行网络请求的相关问题.背景,关于调用第三方的接口都是使用使 ...
- 通过HttpWebRequest请求https接口
一.为什么进行代理接口的开发: 有些项目需要访问被墙了哒网站,比如前不久公司开发项目需要使用google地图的接口,而google在中国被墙了,所有打算做一个代理接口服务,将代理放到国外服务器上,通过 ...
随机推荐
- Java枚举类与常用方法
小简博客 - 小简的技术栈,专注Java及其他计算机技术.互联网技术教程 (ideaopen.cn) 枚举类 如何创建 首先,从名字就可以看出,枚举是一个类,那么我们就可以直接在创建时选择枚举就可以. ...
- Asp.Net在线预览Word文档的解决方案与思路
前几天有个老项目找到我,有多老呢?比我工作年限都长,见到这个项目我还得叫一声前辈. 这个项目目前使用非常稳定,十多年了没怎么更新过,现在客户想加一个小功能:在线预览Word文档. 首先想到的是用第三方 ...
- 攻防世界-MISC:glance-50
这是攻防世界MISC高手进阶区的题目,题目如下: 点击下载附件一,得到一张GIF动图如下 找个网站给分离一下,将gif分离为图片,共201张,然后拼接在一起即可得到flag 所以这道题的flag如下: ...
- Visual Studio 修改NuGet 包缓存路径
Visual Studio 下载的NuGet包默认会缓存到 C:\Users{Windows用户名}.nuget\packages 下,时间一长就会导致 C盘空间严重不足. 那么怎样去设置,让包缓存文 ...
- [AcWing 797] 差分
点击查看代码 #include<iostream> using namespace std; const int N = 1e5 + 10; int a[N], b[N]; void in ...
- 使用Typora + 阿里云OSS + PicGo 打造自己的图床
使用Typora + 阿里云OSS + PicGo 打造自己的图床 为什么要打造图床? 让笔记远走高飞 试问以下场景: 我们要把 markdown 笔记放到某博客上,直接进行复制即可.但因你的图片存储 ...
- 详解Kubernetes存储体系
Volume.PV.PVC.StorageClass由来 先思考一个问题,为什么会引入Volume这样一个概念? " 答案很简单,为了实现数据持久化,数据的生命周期不随着容器的消亡而消亡. ...
- ElasticSearch7.3学习(二十四)----相关度评分机制详解
1.算法介绍 relevance score(相关性分数) 算法,简单来说,就是计算出,一个索引中的文本,与搜索文本,他们之间的关联匹配程度.Elasticsearch使用的是 term freque ...
- zabbix 1.2
1.zabbix图形界面乱码问题处理 2.自定义监控项 (1)在agent端配置agent.conf 打开vim /etc/zabbix/zabbix-agent.conf 找到UserP ...
- 五、redis哨兵两套环境同一局域网容灾切换问题
上周遇到个灵异事件,实验室有两套环境来搭建redis集群和哨兵,分别是: 第一套环境IP:67(master) 65(salve) 66(salve)第二套环境IP:115(master) 116(s ...