IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> 解决Cipher Suites导致的“未能创建 SSL/TLS 安全通道”异常问题 -> 正文阅读

[网络协议]解决Cipher Suites导致的“未能创建 SSL/TLS 安全通道”异常问题

故障描述

昨天晚上在生产环境的某台计算机遇到了访问第三方应用报“未能创建 SSL/TLS 安全通道”的异常。开发的同事重新写了两个命令控制台程序(.net framework 4.5 和 .netcore 3.1),问题可以100%重现。同样的代码在本地或者其它服务器上运行,可以正常使用。更为奇怪的是,同事使用 curl 工具或者 Python?写的测试代码竟然都可以正常运行。

环境描述

操作系统: windows server 2016 Datecenter (Azure标准镜像)

Host: China Azure

.Net Runtime:?.net framework 4.7.2 和?.netcore 3.1

Target Framework:.net framework 4.5.1?和 .netcore 3.1均可以重现

测试程序核心代码(.net framework 4.5.1):

ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

HttpWebRequest req = WebRequest.Create(url) as HttpWebRequest;
HttpWebResponse res = (HttpWebResponse)req.GetResponse()

分析

先不考虑 curl 工具或者 Python?写的测试代码为什么可以正常运行,首先还是要先抓取服务器上的网络包进行分析。抓取后发现在Client Hello之后出现了Encrypted Alert。

?回顾一下SSL/TLS握手流程(网图侵删):

?在client hello的时候提供了?version、cipher suites等信息。然后继续看一下网络抓包发现错误代码40(十六进制28转十进制)

?查找到错误代码解释:Indicates that the sender was unable to negotiate an acceptable set of security parameters given the options available. This is a fatal error.

?(SSL/TLS Alert Protocol and the Alert Codes )

第一个参数02表示 AlertLevel,第二个参数28(十进制的40)表示 AlertDescription。那么问题因该出在client hello的时候传入的参数上了。比较常见的是version问题,但是代码里面已经明确声明了使用 TLS 1.2 的版本,而且在其它环境运行也正常说明 TLS 的版本不会有问题。这时候查到一篇文章(How to fix the SSL / TLS handshake failed error)对我起了很大作用。按顺序我开始排查Encryption suite mismatch问题。

因为对方网站可以被外网访问到,所以我考虑使用ssllabs网站的工具进行一下检测,生成一份SSL Report。这里可以看到目标网站支持哪些 Cipher Suites。

?然后发现抓取的网络包里面client hello时没有匹配的 Cipher Suites!?

然后检查本地的成功的请求和服务器上使用 curl 或者?Python?写的测试代码的请求,发现在这一步Cipher Suites的差异很大。下图是使用 curl 的网络包情况。

这个时候网上了一下 .Net 程序如何设置Cipher Suites,找到一个记录(issues 22507),发现可以通过以下方式指定。

var sslOptions = new SslClientAuthenticationOptions {
CipherSuitesPolicy  = new CipherSuitesPolicy(new List<TlsCipherSuite>{     
  TlsCipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 })
};
var socketsHttpHandler = new SocketsHttpHandler { SslOptions = sslOptions };
var httpClient = new HttpClient(socketsHttpHandler, true);

httpClient.GetAsync(url).Wait();

不过实际的程序使用的是HttpWebRequest(.net framework 4.5.1)而且其它环境是可以正常使用的,并没有声明过Cipher Suites,所以又发现?The build-in classes?HttpWebRequest and the sort all uses Windows native SChannel to implement SSL encryption, therefore has no programmatic way to control the cipher suite list. (原文),所以开始考虑 OS 配置的问题。Windows Server 2016?Cipher Suite list 我没有查到,但可以参考其它版本的说明(Windows2022)和?How to deploy custom cipher suite ordering in Windows Server 2016?的文章。

实际上我没有担心过windows server 2016不支持相应Cipher Suites的问题,最简单的证明就是其它服务器(同OS版本)是可以正常使用的,所以这台机器应该是进行了特殊的配置。查了一下如何配置(How to Update Your Windows Server Cipher Suite for Better Security),然后打开组策略发现果然被人修改过了。

先恢复成默认值(未配置),再次运行测试程序,通过?。

感言

从发现故障到找到原因,说起来很简单,但实际用了将近四个小时。主要的问题就是基础知识不牢固,SSL的流程原理什么的都是重新学习一遍,大量知识都是现查,甚至一开始方向都没有头绪。工作了十几年了,越发觉得基础知识的重要性。

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-09-27 14:27:29  更:2021-09-27 14:28:15 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 2:00:07-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码