真正“搞”懂HTTPS协议18之TLS特性解析
上一篇,我们讲了TLS的握手过程,我们参照的版本其实是TLS1.2。这个协议是2008年的老协议了,虽然它的价值不言而喻,但是毕竟年纪大了,不太能跟得上时代了。所以,经历了诸多磨难的TLS1.3在2018年也登场了,再次确立了信息安全领域的新标准。那我们先来看看TLS1.3有哪些改进。
一、最大化兼容性
由于1.1、1.2等协议已经出现了很多年,很多应用软件、中间代理等(官方被称为“MiddleBox”)只认老的记录协议格式,就像是HTTP/3抛弃了TCP作为底层的原因类似。更新改造很困难,甚至是不可能的。
在早期的试验中发现,一旦变更了记录头字段里的版本号,也就是由 0x303(TLS1.2)改为 0x304(TLS1.3)的话,大量的代理服务器、网关都无法正确处理,最终导致 TLS 握手失败。
为了保证这些被广泛部署的“老设备”能够继续使用,避免新协议带来的“冲击”,TLS1.3 不得不做出妥协,保持现有的记录格式不变,通过“伪装”来实现兼容,使得 TLS1.3 看上去“像是”TLS1.2。
那怎么办呢?在针对这种协议升级导致的向下兼容问题,其实解决的方案都是殊途同归。就只能包含旧的协议了呗。
在TLS1.3中,用了一个新的“扩展协议”(Extension Protocol),它有点“补充条款”的意思,通过在记录末尾添加一系列的“扩展字段”来增加新的功能,老版本的 TLS 不认识它可以直接忽略,这就实现了“后向兼容”。
在记录头的 Version 字段被兼容性“固定”的情况下,只要是 TLS1.3 协议,握手的“Hello”消息后面就必须有“supported_versions”扩展,它标记了 TLS 的版本号,使用它就能区分新旧协议。
Handshake Protocol: Client Hello
Version: TLS 1.2 (0x0303)
Extension: supported_versions (len=11)
Supported Version: TLS 1.3 (0x0304)
Supported Version: TLS 1.2 (0x0303)
TLS1.3 利用扩展实现了许多重要的功能,比如“supported_groups”、“key_share”、“signature_algorithms”、“server_name”等,这些等后面用到的时候再说。
二、强化安全
TLS1.2 在十来年的应用中获得了许多宝贵的经验,陆续发现了很多的漏洞和加密算法的弱点,所以 TLS1.3 就在协议里修补了这些不安全因素。比如:
- 伪随机数函数由 PRF 升级为 HKDF(HMAC-based Extract-and-Expand Key Derivation Function);
- 明确禁止在记录协议里使用压缩;
- 废除了 RC4、DES 对称加密算法;
- 废除了 ECB、CBC 等传统分组模式;
- 废除了 MD5、SHA1、SHA-224 摘要算法;
- 废除了 RSA、DH 密钥交换算法和许多命名曲线。
嗯……了解下就行了。
经过这一番瘦身后,TLS1.3只保留了AES、ChaCha20对称加密算法,分组模式只能用 AEAD 的 GCM、CCM 和 Poly1305,摘要算法只能用 SHA256、SHA384,密钥交换算法只有 ECDHE 和 DHE,椭圆曲线也被“砍”到只剩 P-256 和 x25519 等 5 种。
算法精简后带来了一个意料之中的好处:原来众多的算法、参数组合导致密码套件非常复杂,难以选择,而现在的 TLS1.3 里只有 5 个套件,无论是客户端还是服务器都不会再犯“选择困难症”了。
至于为啥会废除RSA和DH密钥交换算法呢?因为它不具备“前向安全”(Forward Secrecy)。什么意思呢?
假设有这么一个很有耐心的黑客,一直在长期收集混合加密系统收发的所有报文。如果加密系统使用服务器证书里的 RSA 做密钥交换,一旦私钥泄露或被破解(使用社会工程学或者巨型计算机),那么黑客就能够使用私钥解密出之前所有报文的“Pre-Master”,再算出会话密钥,破解所有密文。这就是所谓的“今日截获,明日破解”。
而 ECDHE 算法在每次握手时都会生成一对临时的公钥和私钥,每次通信的密钥对都是不同的,也就是“一次一密”,即使黑客花大力气破解了这一次的会话密钥,也只是这次通信被攻击,之前的历史消息不会受到影响,仍然是安全的。所以现在主流的服务器和浏览器在握手阶段都已经不再使用 RSA,改用 ECDHE,而 TLS1.3 在协议里明确废除 RSA 和 DH 则在标准层面保证了“前向安全”。
三、提升性能
HTTPS 建立连接时除了要做 TCP 握手,还要做 TLS 握手,在 1.2 中会多花两个消息往返(2-RTT),可能导致几十毫秒甚至上百毫秒的延迟,在移动网络中延迟还会更严重。
现在因为密码套件大幅度简化,也就没有必要再像以前那样走复杂的协商流程了。TLS1.3 压缩了以前的“Hello”协商过程,删除了“Key Exchange”消息,把握手时间减少到了“1-RTT”,效率提高了一倍。咋搞的呢?
其实具体的做法还是利用了扩展。客户端在“Client Hello”消息里直接用“supported_groups”带上支持的曲线,比如 P-256、x25519,用“key_share”带上曲线对应的客户端公钥参数,用“signature_algorithms”带上签名算法。
服务器收到后在这些扩展里选定一个曲线和参数,再用“key_share”扩展返回服务器这边的公钥参数,就实现了双方的密钥交换,后面的流程就和 1.2 基本一样了。我们来看张熟悉的图:
对比之前的图,有啥区别呢?在第一次传递记录的时候,就把支持的版本号吖、key_share等等传递给了服务器,服务器就可以根据这些字段处理数据返回给客户端,换句话说,其实就是打个提前量,减少请求次数。
其实夸张一点,所有的数据交换,来回一次就够了,只需要一个往返,你品品?
四、握手分析
我们直接看下它的流程图,注意对比上一小节的详细握手图,看看它们的区别。
还是四个步骤,我们来过一下噢~
首先还是TCP的三次握手,握手建立TCP连接后,浏览器还是首先发个“Client Hello”,因为 1.3 的消息兼容 1.2,所以开头的版本号、支持的密码套件和随机数(Client Random)结构都是一样的(不过这时的随机数是 32 个字节)。
Handshake Protocol: Client Hello
Version: TLS 1.2 (0x0303)
Random: cebeb6c05403654d66c2329…
Cipher Suites (18 suites)
Cipher Suite: TLS_AES_128_GCM_SHA256 (0x1301)
Cipher Suite: TLS_CHACHA20_POLY1305_SHA256 (0x1303)
Cipher Suite: TLS_AES_256_GCM_SHA384 (0x1302)
Extension: supported_versions (len=9)
Supported Version: TLS 1.3 (0x0304)
Supported Version: TLS 1.2 (0x0303)
Extension: supported_groups (len=14)
Supported Groups (6 groups)
Supported Group: x25519 (0x001d)
Supported Group: secp256r1 (0x0017)
Extension: key_share (len=107)
Key Share extension
Client Key Share Length: 105
Key Share Entry: Group: x25519
Key Share Entry: Group: secp256r1
注意“Client Hello”里的扩展,“supported_versions”表示这是 TLS1.3,“supported_groups”是支持的曲线,“key_share”是曲线对应的参数。
服务器收到“Client Hello”同样返回“Server Hello”消息,还是要给出一个随机数(Server Random)和选定密码套件。
Handshake Protocol: Server Hello
Version: TLS 1.2 (0x0303)
Random: 12d2bce6568b063d3dee2…
Cipher Suite: TLS_AES_128_GCM_SHA256 (0x1301)
Extension: supported_versions (len=2)
Supported Version: TLS 1.3 (0x0304)
Extension: key_share (len=36)
Key Share extension
Key Share Entry: Group: x25519, Key Exchange length: 32
表面上看和 TLS1.2 是一样的,重点是后面的扩展。“supported_versions”里确认使用的是 TLS1.3,然后在“key_share”扩展带上曲线和对应的公钥参数。
这时只交换了两条消息,客户端和服务器就拿到了四个共享信息:Client Random 和 Server Random、Client Params 和 Server Params,两边就可以各自用 ECDHE 算出“Pre-Master”,再用 HKDF 生成主密钥“Master Secret”,效率比 TLS1.2 提高了一大截。
在算出主密钥后,服务器立刻发出“Change Cipher Spec”消息,比 TLS1.2 提早进入加密通信,后面的证书等就都是加密的了,减少了握手时的明文信息泄露。
这里 TLS1.3 还有一个安全强化措施,多了个“Certificate Verify”消息,用服务器的私钥把前面的曲线、套件、参数等握手数据加了签名,作用和“Finished”消息差不多。但由于是私钥签名,所以强化了身份认证和和防窜改。
这两个“Hello”消息之后,客户端验证服务器证书,再发“Finished”消息,就正式完成了握手,开始收发 HTTP 报文。
我们可以看到,其实就是在第一次传递消息的时候,通过扩展协议,减少数据的往返,提前进入数据传递的时间。
五、小结
其实这篇文章和上一篇文章的重点都在于图中,大家要好好消化。要注意TLS1.3相比于TLS1.2有哪些不同点,其实核心就是通过扩展协议来提前把需要参数交换,嗯……就这么简单。
真正“搞”懂HTTPS协议18之TLS特性解析的更多相关文章
- 真正“搞”懂HTTP协议05之What's HTTP?
前面几篇文章,我从纵向的空间到横向的时间,再到一个具体的小栗子,可以说是全方位,无死角的覆盖了HTTP的大部分基本框架,但是我聊的都太宽泛了,很多内容都是一笔带过,再加上一句后面再说就草草结束了.并且 ...
- 真正“搞”懂HTTP协议02之空间穿梭
时隔四年,这个系列鸽了四年,我终于觉得我可以按照自己的思路和想法把这个系列完整的表达出来了. 想起四年前,那时候还是2018年的六月份,那时候我还工作不到两年,那时候我翻译了RFC2616的部分内容, ...
- 真正“搞”懂HTTP协议03之时间穿梭
上一篇我们简单的介绍了一下DoD模型和OSI模型,还着重的讲解了TCP的三次握手和四次挥手,让我们在空间层面,稍稍宏观的了解了HTTP所依赖的底层模型,那么这一篇,我们来追溯一下HTTP的历史,看一看 ...
- 真正“搞”懂http协议01—背景故事
去年读了<图解HTTP>.<图解TCP/IP>以及<图解网络硬件>但是读了之后并没有什么深刻的印象,只是有了一层模糊的脉络,刚好最近又接触了一些有关http的相关内 ...
- 真正“搞”懂HTTP协议08之重定向
我们知道,用来传输页面的协议就是HTTP协议,全称是超文本传输协议,而浏览器展示的页面则是用HTML编写的,HTML的全称则是超文本标记语言.你看,都叫做超文本,我在第一篇文章的时候也详细的聊过,超文 ...
- 真正“搞”懂HTTP协议09之这个饼干不能吃
我们在之前的文章中介绍HTTP特性的时候聊过,HTTP是无状态的,每次聊起HTTP特性的时候,我都会回忆一下从前辉煌的日子,也就是互联网变革的初期,那时候其实HTTP不需要有状态,就是个浏览页面,没有 ...
- 一篇文章搞懂密码学基础及SSL/TLS协议
SSL协议是现代网络通信中重要的一环,它提供了传输层上的数据安全.为了方便大家的理解,本文将先从加密学的基础知识入手,然后展开对SSL协议原理.流程以及一些重要的特性的详解,最后会扩展介绍一下国密SS ...
- 彻底搞懂https原理
我终于彻底理解了https原理!!!激动之下,写一篇博客,搞一波分享!!! 本篇博客比较精彩的地方: 思维方式:也是借鉴一位大佬的,写得很棒.https://blog.csdn.net/guolin_ ...
- 真正“搞”懂HTTP协议07之body的玩法(实践篇)
我真没想到这篇文章竟然写了将近一个月,一方面我在写这篇文章的时候阳了,所以将近有两周没干活,另外一方面,我发现在写基于Node的HTTP的demo的时候,我不会Node,所以我又要一边学学Node,一 ...
- 真正“搞”懂HTTP协议11之代理服务
代理,其实全称应该叫做代理服务器,它是客户端与服务器之间得中间层,本质上来说代理就是一个服务器,在HTTP的链路中插入的一个中间环节,就是代理服务器啦.所谓的代理服务就是指:服务本身不生产内容,而是处 ...
随机推荐
- 2022春每日一题:Day 41
题目:I Hate It 一个基础的线段树模板,单点修改+区间查询 代码: #include <cstdio> #include <cstdlib> #include < ...
- SolidWorks2020下载安装中文版教程,你solidworks安装失败是什么原因?
SW2020 WIN10 64位安装步骤: 1.先使用"百度网盘客户端"下载SW20S5_CN_x64安装包到电脑磁盘英文路径文件夹里,并鼠标右击进行解压缩,安装前先断开电脑网络, ...
- 编码工具使用(go语言)
1.课程介绍 Git基础课程和实操 Goland介绍以及常用快捷键使用 Go delve 调试 你想要的linux 这里都有 2.版本控制工具介绍 原始的版本控制 修改文件,保存文件副本 版本控制的起 ...
- ThinkPHP 6.0 RC2 版本发布——架构升级、精简核心
自从5.2版本变更为6.0以来,官方一直致力于优化架构和精简核心,同时也在准备手册和测试工作,在经过近1个月的开发迭代后,官方宣布发布ThinkPHP6.0RC2版本. 主要更新 相比较RC1版本更新 ...
- Python基础之数据库:5、创建表的完整语法、MySQL数据类型
一.创建表的完整语法 1.创建表的语法 create table 表名( 字段名1 字段类型(数字) 约束条件, 字段名2 字段类型(数字) 约束条件, 字段名3 字段类型(数字) 约束条 ...
- 如何使用虚拟机下载和安装Centos
首先先下载虚拟机进行安装我这里使用的是 VMware Workstation Player 当前版本为16.这个是免费使用的可以不需要许可证就能长期使用了 官网VMware Workstation P ...
- Permanently added the RSA host key for IP address '192.30.253.113' to the list of known hosts.
$git push origin master 报错: Warning: Permanently added the RSA host key for IP address '192.30.253.1 ...
- 【Hive】概念、安装、数据类型、DDL、DML操作、查询操作、函数、压缩存储、分区分桶、实战Top-N、调优(fetch抓取)、执行计划
一.概念 1.介绍 基于Hadoop的数据仓库工具,将结构化数据映射为一张表,可以通过类SQL方式查询 本质:将HQL转换成MapReduce程序 Hive中具有HQL对应的MapReduce模板 存 ...
- mouseMove模拟拖拽,封装指令
最近项目里常常使用拖拽改变元素位置或者大小的需求,cv法文件找的脑阔疼,索性试试写一个指令. 说起指令,提一嘴,vue3没有了根元素唯一的限制后,仿佛指令绑定在组件上就不能生效了. import ty ...
- C#实现文件导入与导出
无论是文件的导入与导出都需要引入IO库,引入方法如下: using System.IO; 通过以下代码可以实现将文件导入到数组中 string path;//定义一个路径 OpenFileDialog ...