第1章 TLS概述:从握手到加密,我们为什么离不开它
如果你写过网络程序,一定和 TLS 打过交道。它的全称是 Transport Layer Security,中文叫传输层安全协议。说白了,就是在互联网上给数据穿一层防弹衣。
我经常被问到:TLS 到底解决了什么问题?答案很简单——你发的数据包,中间人能不能看懂?能不能篡改?能不能假装是你?TLS 把这三件事全办了。我在项目中遇到过最典型的场景:某电商的登录接口走了明文 HTTP,结果用户密码被运营商插入了恶意脚本……从那以后,我再也不允许任何对内对外接口跳过 TLS。
1.1 TLS 协议发展史:从 SSL 到 TLS 1.3
故事要从 90 年代讲起。网景公司(Netscape)为了给浏览器通信加密,搞出了 SSL(Secure Sockets Layer)。SSL 1.0 从未公开,2.0 在 1995 年发布,但漏洞多到让人崩溃——我记得看过一篇,说 SSL 2.0 的握手消息没有完整性保护,中间人可以轻易降级攻击。
1996 年,SSL 3.0 发布,算是第一个相对靠谱的版本。但好景不长,1999 年 IETF 接手,把 SSL 标准化成了 TLS 1.0——其实改动不大,但从此名字就变了。
关键时间线:
- 1995 SSL 2.0 —— 第一个商用版本,已废弃
- 1996 SSL 3.0 —— 奠基之作,2015 年被 POODLE 攻击彻底终结
- 1999 TLS 1.0 —— 与 SSL 3.0 基本兼容,慢慢替换
- 2006 TLS 1.1 —— 主要修复 CBC 攻击,加了显式 IV
- 2008 TLS 1.2 —— 支持 SHA-256、AEAD 密码套件,至今仍是主流
- 2018 TLS 1.3 —— 大幅简化握手、移除不安全算法,性能和安全双赢
你想想看,从 TLS 1.0 到 1.3,走了将近 20 年。我在 2015 年迁移一个老系统时,发现对方只支持 TLS 1.0,但安全扫描直接报高危——没办法,只能加个 Nginx 反协议转换。嗯,这里要记住:生产环境至少禁用 TLS 1.0/1.1,这是底线。
| 版本 | 发布年份 | 核心改进 | 当前状态 |
|---|---|---|---|
| SSL 2.0 | 1995 | 首次商用加密 | 已废弃(严重漏洞) |
| SSL 3.0 | 1996 | 握手改进、消息认证 | 已废弃(POODLE 攻击) |
| TLS 1.0 | 1999 | 标准化,兼容 SSL 3.0 | 禁止使用(BEAST 攻击) |
| TLS 1.1 | 2006 | 显式 IV,修复 CBC 问题 | 禁止使用 |
| TLS 1.2 | 2008 | AEAD、SHA-256、密码套件更灵活 | 广泛使用(推荐) |
| TLS 1.3 | 2018 | 0-RTT、1-RTT 握手、移除不安全算法 | 最新标准(强烈推荐) |
1.2 TLS 到底在做什么?
三个核心作用:加密、身份验证、完整性校验。我用一个类比帮你理解——
- 加密:就像把信装进保险箱,只有收件人有钥匙打开。
- 身份验证:不仅看钥匙,还要确认锁芯上刻的“深圳总公司”字样是真的,不是伪造的。
- 完整性:信送到后,检查保险箱有没有被撬过的痕迹——数据有没有被中间人篡改。
TLS 通过“握手”(Handshake)阶段完成这三件事。握手过程可以简单概括:
- 客户端发送支持的加密算法列表(ClientHello)
- 服务端选一套算法并发送证书(ServerHello + Certificate)
- 客户端验证证书合法性,生成对称密钥并加密发送给服务端
- 双方各用对称密钥加密数据,开始安全通信
1.3 应用场景:离开 TLS 寸步难行
你猜哪里还不用 TLS?我可以明确说——基本没有了。
- HTTPS(Web 安全):Chrome 已经把所有 HTTP 页面标记为“不安全”,这是最广为人知的应用。
- API 安全:RESTful 接口、gRPC、WebSocket 全部依赖 TLS。我做过一个金融数据平台,所有微服务之间的通信强制双向 mTLS,连内部 DNS 查询都走了 DoT(DNS over TLS)。
- 数据库连接加密:MySQL、PostgreSQL、MongoDB 都支持 TLS 加密客户端到服务器的传输。我记得有一次线上事故,就是因为没开数据库 TLS,被一个运维误操作在公网抓到了全部业务数据……嗯,教训深刻。
- 邮件安全:SMTP、IMAP、POP3 的 TLS 加密,防止密码和邮件内容泄漏。
- VPN 与远程访问:OpenVPN、IPsec 底层也大量使用 TLS 做密钥交换。
- 物联网(IoT):小型设备用 DTLS(TLS 的 UDP 版本)进行轻量级加密。
你想想看,现在还有什么网络流量是纯明文的?恐怕只有一些老旧的内部监控协议了——但这种东西,迟早也要被 TLS 吞掉。
1.4 版本差异:选哪个?怎么选?
这是开发同学最常问的问题。我直接给结论:只保留 TLS 1.2 和 TLS 1.3。理由如下:
| 对比项 | TLS 1.2 | TLS 1.3 |
|---|---|---|
| 握手轮次 | 2-RTT(完整握手) | 1-RTT(普通),0-RTT(带缓存) |
| 支持的密码套件 | 几十种(很多已不安全) | 仅 5 种强力 AEAD 套件 |
| 前向安全性 | 可选(需指定 ECDHE) | 强制所有密钥交换都支持 |
| 握手中证书交换 | 明文传输 | 加密部分握手消息 |
| 会话恢复 | Session ID / Session Ticket | PSK + 0-RTT |
| 兼容性 | 最广泛(连 Win7 IE 都支持) | 需要较新操作系统和库(OpenSSL 1.1.1+) |
另外还要注意一个坑:密码套件优先级。很多人以为只要开启 TLS 1.3 就万事大吉,但实际配置中,服务端算法列表的顺序决定了实际使用的套件。我曾经见过一个配置,把 CBC 模式的套件放在 ECDHE 前面——结果高性能 TLS 1.2 握手也慢得离谱。所以记得调优:优先使用 AEAD + ECDHE。
# Nginx 推荐配置示例(仅 TLS 1.2 + 1.3)
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers on;
为什么我推荐这样配?因为前四个密码套件都是 AEAD(认证加密),而且全部基于 ECDHE 密钥交换,保证了前向安全性。如果你发现某些老设备连不上,再加一个 RSA 密钥交换的套件——但要放在最后,作为降级兜底。
这张图把 TLS 六个主要版本按时间轴排开,顺便标了当前安全状态。你看,到了 TLS 1.2 和 1.3 才算是真正“能用”的版本——前面四个,基本全是考古级漏洞。
小结
这一章我们聊了三件事:TLS 从哪里来、它能干什么、怎么选版本。说白了,TLS 就是互联网安全的基石,没有它,你的所有在线操作都是裸奔。
嗯,最后留一个习惯:每次启动新项目,第一件事就是检查 TLS 配置。我之前接手的几个老旧系统,都是上来先补 TLS 证书——不夸张,经常能发现服务居然还在用自签名证书裸跑。这种问题,越早修越好。