TLS协议基础
聊性能优化之前,得先把TLS协议本身摸透。我见过不少团队一上来就调参数,结果因为用了过时的版本或弱加密套件,安全都保不住,性能分析更是白折腾。这一章我们就从版本演进、加密套件、协议栈结构三个角度把地基打牢。
1.1 TLS版本演进史
说白了,TLS就是SSL的升级版。1995年网景搞出SSL 2.0,结果漏洞一堆。1996年SSL 3.0出来,算是勉强能用。后来IETF接手,1999年发布TLS 1.0(相当于SSL 3.1),2006年TLS 1.1,2008年TLS 1.2,2018年TLS 1.3。
| 版本 | 发布年份 | 核心变化 | 安全状态 | 性能特点 |
|---|---|---|---|---|
| SSL 2.0 | 1995 | 最早商用版本 | 已废弃,严重漏洞 | 极差 |
| SSL 3.0 | 1996 | 引入主密钥、改进握手 | 已废弃(POODLE攻击) | 差 |
| TLS 1.0 | 1999 | 标准化,PRF改进 | 已废弃(BEAST攻击) | 慢 |
| TLS 1.1 | 2006 | 隐式IV,CBC防御 | 不推荐 | 中等 |
| TLS 1.2 | 2008 | AEAD支持,SHA-256 | 广泛使用 | 较好 |
| TLS 1.3 | 2018 | 1-RTT握手,移除不安全算法 | 当前推荐 | 优 |
1.2 核心加密套件
加密套件就是一组算法的组合,告诉双方怎么握手的。格式类似:密钥交换_身份认证_对称加密_消息认证。举个例子,ECDHE-RSA-AES128-GCM-SHA256:
- ECDHE – 临时椭圆曲线Diffie-Hellman密钥交换(前向安全)
- RSA – 用RSA证书做身份认证
- AES128-GCM – 128位AES-GCM对称加密(AEAD)
- SHA256 – 消息认证用SHA-256 HMAC
你想想看,TLS 1.3砍掉了多少套件?直接从TLS 1.2的37个缩到5个。为什么?因为那些带CBC、带RC4的算法又慢又不安全。我建议在生产环境只开放TLS 1.2以上的套件,且优先用ECDHE + AEAD。
| 套件名称 | 密钥交换 | 认证 | 加密 | MAC | 适用场景 |
|---|---|---|---|---|---|
| ECDHE-RSA-AES128-GCM-SHA256 | ECDHE | RSA | AES-128-GCM | 内建AEAD | 通用推荐 |
| ECDHE-ECDSA-AES256-GCM-SHA384 | ECDHE | ECDSA | AES-256-GCM | 内建AEAD | 高安全需求 |
| DHE-RSA-AES128-CBC-SHA | DHE | RSA | AES-128-CBC | SHA-1 | 遗留兼容(不推荐) |
| TLS_CHACHA20_POLY1305_SHA256 | ECDHE | 任意 | CHACHA20-POLY1305 | 内建AEAD | 移动端/无AES加速 |
openssl ciphers -v 'HIGH:!aNULL:!eNULL:!LOW:!MEDIUM'先列一遍系统支持的套件,再按性能测试结果挑前三位。避免选到那些纯软件跑很慢的CBC套件。
1.3 TLS协议栈结构
TLS协议是分层的,跟TCP/IP很像。底层是记录层(Record Layer),上面跑握手协议、警报协议和应用数据协议。做性能优化时,我们最关心的就是记录层的开销和握手协议的RTT数。
下面这张图是我自己梳理的协议栈结构,画了好几次才满意。你注意看,握手协议里面又分成好几个子消息,TLS 1.3比1.2合并了一些步骤。
嗯,这里要注意:握手协议里最耗时的部分往往是证书验证和非对称密钥协商。我在一个高并发API网关项目里遇到过,每次握手光证书链校验就要吃掉2~3毫秒,后来启用OCSP Stapling和会话复用,才算把平均建连时间压到1毫秒以下。
TLS_RSA_WITH_AES_128_CBC_SHA,被安全审计打了个高危。后来我帮他们改成了ECDHE套件,握手多了一次椭圆曲线运算,但安全性和性能都更均衡。
总结一下:版本越新性能越好,但得评估客户端兼容性;加密套件优先选AEAD+ECDHE;协议栈里记录层的MTU和握手子消息的RTT数是最值得优化的两个点。这些基础概念,后面几章会反复用到。