2. HTTPS 与 TLS 基础:SSL/TLS 握手过程、证书链与信任体系、公钥与私钥
说实话,很多人觉得 HTTPS 就是「在 HTTP 外面加了个 S」。嗯,这个说法没错,但太笼统了。我做了这么多年运维,见过太多人把证书配好就以为万事大吉,结果轮换时才发现根本不懂底层原理。
这一章,咱们把 TLS 的核心拆开揉碎。你不需要记住所有细节,但得理解它为什么安全、怎么工作的。
2.1 公钥与私钥:非对称加密的「锁」与「钥匙」
先讲个最基础的概念。你想想看,如果两个人要偷偷传纸条,最直接的办法是什么?约定一个密码,比如「所有字母往后移三位」。这就是对称加密——加密和解密用同一个密钥。
但问题来了:这个密钥怎么安全地传给对方?
这就是非对称加密要解决的。它生成一对密钥:
- 公钥:可以公开给任何人,像一把锁
- 私钥:必须严格保密,像一把钥匙
用公钥加密的数据,只有对应的私钥能解开。反过来,用私钥签名的数据,公钥可以验证签名是否有效。
核心原则:公钥加密,私钥解密;私钥签名,公钥验签。这两个方向不能搞反。
我在项目中遇到过有人把私钥直接放在代码仓库里……嗯,那场面,不说了。记住:私钥一旦泄露,整个信任体系就崩塌了。
2.2 SSL/TLS 握手过程:一次安全的「接头暗号」
TLS 握手,说白了就是客户端和服务器互相确认身份、协商加密参数的过程。我习惯把它分成四个阶段:
- Hello 阶段:双方打招呼,交换支持的加密套件、TLS 版本
- 证书交换:服务器把自己的证书链发给客户端
- 密钥协商:客户端验证证书后,生成一个随机密钥,用服务器公钥加密发过去
- 握手完成:双方用这个对称密钥开始加密通信
为什么要有这么复杂的流程?因为非对称加密太慢了,不适合加密大量数据。所以 TLS 只用它来安全地传递一个临时对称密钥,后续通信都用对称加密。
我的建议:生产环境务必使用 TLS 1.2 或 1.3。TLS 1.0 和 1.1 已经废弃了,别再用。
下面这张图把握手流程画清楚了:
2.3 证书链与信任体系:谁给你的证书「背书」?
好,现在客户端拿到了服务器的证书。但问题来了:我怎么知道这个证书是真的?
这就是证书链要解决的。一个证书不是孤立存在的,它上面有一串「担保人」:
- 根证书:信任的起点,由浏览器/操作系统内置
- 中间证书:根证书签发的「二级担保人」
- 服务器证书:你网站实际使用的证书
验证过程就像查户口:客户端拿到服务器证书后,看它是不是由某个中间证书签发的,再看中间证书是不是由根证书签发的。如果整条链都能追溯到受信任的根证书,那就没问题。
我曾经踩过的坑:有一次部署证书时只上传了服务器证书,没带中间证书。结果安卓手机访问正常,但某些旧版 iOS 浏览器报错「证书不受信任」。后来排查才发现,iOS 没有缓存中间证书,需要服务器完整下发证书链。
证书链的结构可以用表格来理解:
| 层级 | 谁签发 | 谁持有 | 有效期 |
|---|---|---|---|
| 根证书 | 自签名 | CA 机构 | 10-20 年 |
| 中间证书 | 根证书 | CA 机构 | 5-10 年 |
| 服务器证书 | 中间证书 | 你的网站 | 90 天 - 1 年 |
你可能会问:为什么要有中间证书?直接让根证书签发服务器证书不行吗?
嗯,理论上可以。但根证书太重要了,一旦泄露整个互联网都得瘫痪。所以 CA 机构把根证书锁在保险柜里,日常签发用中间证书。就算中间证书出问题,吊销它就行,不影响根证书。
2.4 证书内容:里面到底写了什么?
一个 X.509 证书,说白了就是一张「数字身份证」。我习惯用 OpenSSL 命令查看:
openssl x509 -in example.crt -text -noout
输出里你会看到这些关键字段:
- Subject:证书持有者信息,比如你的域名
- Issuer:签发者,也就是上一级 CA
- Validity:有效期,包含 Not Before 和 Not After
- Subject Public Key Info:你的公钥
- Signature Algorithm:签名算法,比如 SHA256-RSA
- X509v3 extensions:扩展字段,比如 SAN(主题备用名称)
个人经验:SAN 字段特别重要。以前证书靠 Common Name 匹配域名,现在浏览器只看 SAN。如果你申请的是多域名证书,一定要确认 SAN 里包含了所有需要的域名。
2.5 信任体系:为什么浏览器信任某些 CA?
每个操作系统和浏览器都内置了一份根证书信任列表。这些根证书来自全球几十家受信任的 CA 机构,比如 DigiCert、Let's Encrypt、GlobalSign 等。
当你的服务器证书链能追溯到这些根证书之一时,浏览器就认为它是可信的。反之,如果证书是自签名的,或者 CA 不在信任列表里,浏览器就会弹出「不安全」的警告。
我经常跟团队说:信任体系是一个「信任传递」的过程。你不需要信任每个网站,你只需要信任那几十个根证书。剩下的,由它们来担保。
一句话总结:HTTPS 的安全性建立在「非对称加密传递对称密钥」+「证书链追溯信任根」这两个核心机制上。理解了这个,后面讲证书轮换你就知道为什么私钥不能丢、为什么证书链要完整。