第1章:TLS协议概述——从握手说起的加密旅程
各位好,我是你们的讲师。在正式开始配置合规性验证之前,咱们得先统一认知——TLS到底是个什么东西?
我见过不少运维同事直接把“TLS”和“SSL”混着用,甚至还有人觉得HTTPS就是TLS。其实这些概念之间差着辈分呢。今天这一章,我就带你从头捋一遍。
1.1 历史版本:SSL 死了,TLS 活着
故事要从1995年说起。网景公司搞了个叫 SSL 2.0 的东西,目的是让浏览器和服务器之间安全传数据。紧接着 1996 年出了 SSL 3.0,算是第一版广泛使用的安全协议。
后来 IETF 接手了这个活儿,在 1999 年发布了 TLS 1.0(其实本质就是 SSL 3.0 的升级版)。到这里名字换了,但核心框架没大变。
我个人习惯把版本演变画成一张表,你一看就明白:
| 版本 | 发布年份 | 状态 | 我个人的评价 |
|---|---|---|---|
| SSL 2.0 | 1995 | 已废弃 | 漏洞多到像筛子,别碰 |
| SSL 3.0 | 1996 | 已废弃(POODLE攻击后) | 我当年刚入行时还在用它,后来被POODLE搞惨了 |
| TLS 1.0 | 1999 | 已废弃 | 还能在老的Windows XP上见到 |
| TLS 1.1 | 2006 | 已废弃 | 基本是个过渡版本,用得不多 |
| TLS 1.2 | 2008 | 广泛使用 | 目前最稳的主力版本 |
| TLS 1.3 | 2018 | 当前推荐 | 握手更快,更安全,强烈推荐 |
1.2 从 SSL 到 TLS:名字改了,魂没变
TLS 和 SSL 到底有啥区别?说白了:
- SSL(Secure Sockets Layer):网景的私有协议,早期版本混乱,后来被 IETF 标准化。
- TLS(Transport Layer Security):IETF 接手后改的名字,本质上是 SSL 3.0 的演进版。
但要注意:TLS 1.0 内部版本号是 3.1,TLS 1.1 是 3.2,TLS 1.2 是 3.3。所以很多老库代码里还在用 “SSLv3.1” 这样的字符串来指代 TLS 1.0。你看到别懵。
我遇到过一件事:有一次排查 Nginx 日志,发现客户端报告 “SSLv3”,我第一反应是开了 SSlv3 漏洞。后来细查才发现,是 OpenSSL 的一个历史遗留 bug,把 TLS 1.0 握手记录标记成了 SSLv3。嗯,别被字面迷惑。
1.3 HTTPS 与 TLS 的关系:一个是车,一个是发动机
很多人以为 HTTPS 就是 TLS,这不太准确。我打个比方:
- HTTP 是卡车(传输明文数据)
- TLS 是发动机(加密保护)
- HTTPS 就是装上了 TLS 发动机的 HTTP 卡车
所以 HTTPS = HTTP over TLS,本质是 HTTP 协议运行在 TLS 安全层之上。浏览器地址栏的绿色小锁,代表的是 TLS 握手成功、证书可信、会话加密。
listen 443 ssl; 这类指令。Nginx 和 Apache 里所谓的 “SSL 配置”,其实配置的都是 TLS 协议参数。别再在配置文件里写 ssl_protocols TLSv1.2 TLSv1.3; 这种自我矛盾的写法了 —— 虽然正确,但看着别扭。
1.4 TLS 握手流程简介:一次加密的握手舞
TLS 握手的核心目标是什么?协商加密算法、验证对方身份、生成对称密钥。这个过程在我们看来是瞬间完成的,但背后其实挺复杂。
我先画一张完整的流程图,咱们一起走一遍:
我习惯把这个过程拆成5个关键步骤:
- ClientHello:客户端告诉服务器“我支持这些TLS版本,这些加密套件”。
- ServerHello + Certificate:服务器选择好版本和算法,把数字证书发给客户端。
- ClientKeyExchange:客户端用服务器公钥加密一个“预主密钥”发给服务器。
- ChangeCipherSpec + Finished:双方协商出对称密钥,并握手完成校验。
- 应用数据加密:之后所有通信都是用对称密钥加密的了。
重点: 第3步里那个“预主密钥”很关键。我记得有一次排查TLS握手失败,OpenSSL日志里报“premaster secret size mismatch”。最后发现是客户端用了不支持的密钥交换算法(比如DH参数长度不匹配)。所以配置合规性验证里,第一步就是要检查加密套件和密钥交换算法是否被正确禁用或启用。
1.5 一个真实案例:SSLv3 还在用,差点被审计毙了
2014年,POODLE攻击爆发,所有SSLv3瞬间变成高危。我接手过一个老系统的改造,Java 1.6 写的,负载均衡器还是 F5 BIG-IP 9.x,默认启用了 SSLv3。客户审计公司的报告写着“严重不符合PCI DSS v3.2要求”。
我当时和运维团队一块排查:先检查应用层有没有硬编码 TLS 版本,然后升级负载均衡固件,最后在 Nginx 端加上 ssl_protocols TLSv1.2 TLSv1.3;。整个改造花了两周,但结果就是:所有 SSLv3 都禁掉了,握手效率反而因为只用 TLS 1.2 以上变得更快了。
1.6 本章小结:我们为什么需要懂这些?
你可能会想:我只是配个 Nginx,知道这些历史干嘛?
我个人的体会是:不懂握手细节,你遇到奇怪的连接失败时根本没方向。比如客户端报告“handshake failure”,你至少要能猜到是版本协商失败还是证书验证失败,还是密钥交换参数不一致。
后面的课程里,我们会用到大量抓包分析(Wireshark + tshark),也会用 OpenSSL 命令手动测试。所以今天这章打底很重要。记住这几个关键点:
- SSL 是旧名称,TLS 是标准名称,不要再混用。
- HTTPS = HTTP over TLS,不是另起炉灶的新协议。
- TLS 1.2 和 1.3 是当前唯二可用的版本。
- 握手分5步,其中密钥交换和证书验证是核心。