更好的 TLS 1.3 协议解析

网络安全篇,面对复杂多变的网络环境,我们需要掌握哪些关于网络安全的相关知识,聊一聊与网络安全相关的:HTTPS、SSL、TLS 等。


网络安全专题
  • 网络安全的基石

网络安全 — HTTPS
网络安全的基石(上)— 加密
网络安全的基石(下)— 完整性与身份认证
公钥信任问题 — 数字证书与 CA
信任始于握手 — TLS 连接过程详解

  • HTTPS 的优化

《TLS 1.3 特性解析》
如何优化 HTTPS 连接》- 待完善


早在 2013 年,IETF(互联网工程小组) 就对 TLS 1.2 的过时设计和两次往返开销心生不满,因此开始着手准备新版本的 TLS。同年 8 月由 Eirc Rescorla 提议出新版本 TLS 的功能愿望清单。在经过一番辩论后,最终该提议内容被定义为 TLS 1.3。推动 TLS 1.3 设计的主要问题大概有:

  • 减少握手延迟
  • 加密更多的握手
  • 提高抵御跨协议攻击的弹性
  • 删除旧功能

终于在 2018 年 8 月 10 日,历经 4 年时间,TLS 1.3 最终版本发布了 — RFC-8446。新的协议使得互联网变得更快、更安全;随着 TLS 1.3 的采用率不断提高,它势必会长远影响互联网的发展;同时尽快将 TLS 1.3 平滑应用到线上环境无疑是势在必行。

不过在这之前, TLS 1.2 的应用也已经有 10 年(2008 年)的时间了,毕竟历经了种种考验,新的协议在推广和部署上必定会带来新的挑战。接下来我们就来看看新版本的 TLS 是如何做的?

“岁月不饶人”,如今互联网的发展已使 TLS 1.2 在安全、性能等方面不能满足如今的需求。


兼容性

由于 TLS 1.1/1.2 等协议已经出现了很多年,很多应用软件、中间代理(Middlebox)只认老的记录协议格式,更新改造很困难,甚至僵化。

可部署性

正式由于这些中间代理/软件(Middlebox)在新的更改中表现不佳,即使是对 TLS 1.3 协议的细微更改(例如消除冗余的 ChangeCipherSpec 消息,版本号从 0x03 升级为 0x04),也最终导致了某些设备的连接失败问题。这也是 TLS 1.3 从草稿到最终发布花费了这么长时间的重要原因之一。

为了保证这些被广泛部署的“旧设备”能够继续使用,TLS 1.3 不得不做出妥协,通过“伪装”来实现兼容:保持现有的记录格式不变,使得 TLS 1.3 看上去“像是” TLS 1.2。

扩展协议

那么,如何区分是 1.2 还是 1.3 呢?

这里用到一个新的扩展协议(Extension Protocol),它有点“补充条款”的意思,通过在记录末尾添加一系列的“扩展字段”来增加新的功能,旧版本的 TLS 不认识它可以直接忽略,这就实现了“向后兼容”。

在记录头的 Version 字段被兼容性“固定”的情况下,只要是 TLS 1.3 协议,握手的 “Hello” 消息后面就必须有 “supported_versions” 扩展,它标记了 TLS 的版本号,使用它就能区分新旧协议。

Handshake Protocol: Client Hello
    Version: TLS 1.2 (0x0303)
    Extension: Supported_versions (len=11)
        Supported Version: TLS 1.3 (0x304)
        Supported Version: TLS 1.2 (0x0303)

TLS 1.3 正是利用扩展实现了许多重要的功能,比如 “supported_groups” “key_share” “signature_algorithms” “server_name” 等。


强化安全

在经历十余年的实践中获得许多宝贵经验的 TLS 1.2 陆续发现了很多的漏洞和加密算法的弱点。因此消除潜在的危险设计来纠正以前的错误成为 TLS 1.3 的设计目标之一。所以新版本的 TLS 协议里要修补这些不安全的因素。

例如:

  • 伪随机函数由 PRF 升级为 HKDF(HMAC-based Extract-and-Expand Key Derivation Function);
  • 明确禁止在记录协议里使用压缩;
  • 废除了 RC4、DES 对称加密算法;
  • 废除了 ECB、CBC 等传统分组模式;
  • 废除了 MD5、SHA1、SHA-244 摘要算法;
  • 废除了 RSA、DH 密钥交换算法和许多命名曲线。

固定密钥交换

经过这样一番“减肥瘦身”之后,TLS 1.3 的密钥交换算法只有 ECDHE 和 DHE 了,关于椭圆曲线(ECC)也被“砍”到只剩 P-256 和 x25519 等 5 种。

首先来说下废除 RSA 和 DH 密钥交换算法的原因:

由于客户端默认会选择 ECDHE 而非 RSA 做密钥交换,这是因为它不具有“前向安全”(Forward Secrecy):“假设有人长期记录了加密的数据,然后在后续的某个时间段获得了服务器的 RSA 私钥,那么黑客就能够使用该私钥解密出之前所有报文的 “Pre-Master”,再计算出会话密钥,破解所有密文。这便是今日截获,明日破解

而 ECDHE 算法在每次握手时都会生成一对临时公钥和私钥,每次通信的秘钥对都是不同的,也就是“一次一密”,即使黑客花大力气破解了这一次的会话密钥,也只是这次通信被攻击,之前的历史消息不会受到影响,仍然是安全的。

所以现在主流的服务器和客户端在握手阶段都已经不再使用 RSA,改用 ECDHE,而 TLS 1.3 在协议里明确废除了 RSA 和 DH 则在标准层面保证了“前向安全”。

暂时性 DH 成为在 TLS 1.3 中唯一的密钥交换机制。

固定密码

多年以来,密钥交换机制不是唯一引起安全漏洞的部分,对称密钥部分也有相当一部分问题。

同样,用于对称加密的算法在经过“减肥瘦身”之后也只保留了 AES、ChaCha20 ,分组模式只能用 AEAD 的 GCM、CCM 和 Poly1305,摘要算法也只能用 SHA 256、SHA 384。

这样原来众多的加密算法、参数组合导致密码套件非常复杂,难以选择。而经过瘦身之后的 TLS 1.3 只剩下 5 个套件,使得客户端或服务端在选择密码套件时变得“更加容易”。然而更重要的是,这些算法在 TLS 长期的实践过程中先后已经被证实是构成不安全的因素,从而导致安全漏洞。

修复数字签名

经过前面的学习,相信你也知道 TLS 另一个重要部分是身份验证。在每个连接中服务都是用具有公钥的数字证书向客户端提供身份认证。在 RSA 加密模式下,服务器通过解密预主密钥并通过对话记录计算 MAC 来证明其对私钥的所有权。在 Diffie-Hellman 模式下,服务器使用数字签名来证明私钥的所有权。

在 TLS 1.2 和更早的版本中,服务器的签名仅涵盖部分握手。用于协商使用哪种对称密码的部分没有由私钥签名。这也导致许多引人注目的漏洞 FREAKLogJam 等。而在 TLS 1.3 由于服务器对整个握手记录进行签名,因此可以避免这些情况。


提升性能

HTTPS 建立连接时除了要做 TCP 握手,还要做 TLS 握手,在 TLS 1.2 中会多花两个消息往返(2 - RTT),这可能导致几十毫秒甚至上百毫秒的延迟,在移动网络中延迟还会更严重。

1-RTT 模式

密码套件的大幅度简化,也就没有必要再像以前那样走复杂的的协商流程了。TLS 1.3 压缩了以前的 “Hello” 协商过程,删除了 “Key Exchange” 消息,把握手时间减少到了 “1-RTT”,效率提高了一倍。

下面是 TLS 1.3 握手过程的简图,注意与前面介绍的 TLS 1.2 对比区别在哪里。

0-RTT 恢复

除了标准的 “1-RTT” 握手,受 QUIC 协议的启发,客户端可以在其第一条消息中将加密的数据发送到服务器,与未加密的 HTTP 相比,没有额外的延迟成本。

在 TLS 1.2 中,有两种恢复连接的方法:会话 ID 和会话 Ticket,而 1.3 则将他们组合在一起形成称为 PSK(pre-shared key,预共享密钥)恢复的新模式。

握手分析

目前 Nginx 等 Web 服务器都能够很好的支持 TLS 1.3,但是要求底层的 OpenSSL 必须是 1.1.1。因此如果要部署需要先升级你的 OpenSSL 版本。

首先TCP 建立连接之后,浏览器首先还是发一个 “Client Hello”。

由于 1.3 的消息要兼容 1.2,所以开头的版本号、支持的密码套件和随机数(Client Random)结构都是一样的(这时的随机数是 32 个字节)。

Handshake Protocol: Client Hello
    Version: TLS 1.2 (0x0303)
    Random: cebeb6c05403654d66c23290...
    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: seco256r1

注意 “Client Hello” 里的扩展,“supported_versions” 表示这是 TLS 1.3,“supported_groups” 是支持的曲线,“key_share”是曲线对应的参数。

这有点是像是“有话尽量一口气说完”,还是按照老规矩进行“打招呼”,我这边有这些信息,考虑到版本升级,所以附带了一些信息,可能后面会用到。

服务器收到 “Client Hello” 同样返回 “Server Hello” 消息,还是要给出一个随机数(Server Random)和选定密码套件。

Handshake Protocol: Server Hello
    Version: TLS 1.2 (0x0303)
    Random: 12d2bce568bodedi3ee9...
    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: 0x25519, Key Exchange length: 32

表面上看 Version 和 TLS 1.2 是一样的,重点是后面的扩展。“supported_versions” 里确认使用的是 TLS 1.3,然后在 “key_share” 扩展带上曲线和对应的公钥参数。

服务器的回应还是老套路,服务端对客户端的提供的信息作出选择,另外服务端还要再附加上几个参数,这次加密就协商定了。

可以看到相比 TLS 1.2 的握手过程,TLS 1.3 仅用两条消息就共享了 4 个信息:Client RandomServer RandomClient ParamsServer Params。两边就可以各自用 DH 算出 “Pre-Master”,再用 HKDF 生成主密钥 “Master Secret”,效率比 TLS 1.2 提高了一大截。

在计算出主密钥后,服务器立刻发出 “Change Cipher Spec” 消息,比 TLS 1.2 提早进入加密通信,后面的证书等就都是加密的了,减少握手时明文信息泄露。

TLS 1.3 还多了一个 “Change Cipher Spec” 消息,服务器用私钥把前面的曲线、套件、参数等握手数据加了签名,作用和 “Finished” 消息差不多。但由于是私钥签名,所以强化了身份认证和防篡改。

两个“打招呼”消息之后,客户端验证服务器证书,再发 “Finished” 消息,就正式完成了握手,开始收发 HTTP 报文。

现在已经有很多网站都支持了 TLS 1.3,例如 GitHub


最后

今天我们主要介绍了 TLS 1.3 的一些新特性,简单总结下来主要包含下面几点:

  1. 为了兼容旧的版本协议,TLS 1.3 不得不伪装成 TLS 1.2 的外表,将新特性在“扩展”中实现;
  2. TLS 在之前的实践应用中,陆续发现了很多安全隐患,因此消除这些危险因素成了 TLS 1.3 的设计目标之一,其中包含大幅删减了一些已经被证实存在安全隐患的加密算法,从协议层面进一步强化了安全。
  3. TLS 1.3 还简化了握手过程,只需要一个消息往返便可实现完全握手。

TLS 1.3 涉及的内容很多,有关它的更详细信息请去参照 RFC-8446,关于这部分大家还有哪些要分享的呢?欢迎您的留言或指正。


网络安全系列专题

扩展阅读

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335