一、安全通信的四个属性
| 属性 | 含义 | 靠什么实现 |
|---|---|---|
| ⭐ 机密性(Confidentiality) | 只有发送方和接收方能理解内容 | 加密 |
| ⭐ 完整性(Integrity) | 内容未被篡改(或篡改能被检测) | MAC / 数字签名 |
| ⭐ 认证(Authentication) | 双方能确认对方的身份 | 挑战-响应 / 证书 |
| 可用性(Availability) | 服务可被合法用户访问 | 抗 DDoS、冗余 |
⚠️ 四者互相独立,缺一不可。
只有机密性没有完整性 → 攻击者虽读不懂,但可以【翻转密文比特】造成可预测的明文改变
只有完整性没有认证 → 你确认消息没被改,但不知道是谁发的
只有认证没有机密性 → 你知道是他发的,但所有人都能读
📌 一个真实的教训:早期的 WEP(第 25 讲)加密了内容但完整性保护极弱,攻击者可以在不解密的情况下篡改分组——加密不等于安全。
二、对称密钥密码
2.1 基本模型
Alice Bob
│ │
明文 m ──[加密 K_s]──▶ 密文 ──[解密 K_s]──▶ 明文 m
│
⭐ 双方共享【同一个】密钥
2.2 从替换密码到分组密码
凯撒密码/单表替换:每个字母映射到另一个字母。
⚠️ 靠频率分析几分钟就能破解——英文中 e 出现频率最高,密文中出现最多的字母就是 e。
分组密码(Block Cipher):现代做法。把明文切成固定长度的分组,每组用密钥做多轮的替换 + 置换。
| 算法 | 分组 | 密钥 | 状态 |
|---|---|---|---|
| DES | 64 位 | 56 位 | ⚠️ 已被暴力破解(1997 年起) |
| 3DES | 64 位 | 168 位 | 慢,逐步淘汰 |
| ⭐ AES | 128 位 | 128/192/256 位 | ⭐ 当前标准,有硬件指令加速 |
2.3 分组密码的工作模式 ⭐
关键问题:如果两个明文分组相同,密文也会相同吗?
ECB 模式(电码本):每组独立加密。
⚠️ 相同的明文分组 → 相同的密文分组
→ ⭐ 明文的【结构】完全泄露
📌 著名的"ECB 企鹅"图:用 ECB 加密一张企鹅图片,加密后仍然能清楚看出企鹅的轮廓。这是密码学教学中最有力的一张图。
CBC 模式(密码分组链接):
C_i = E(K, P_i ⊕ C_{i−1}) C_0 = IV(初始向量,随机)
⭐ 每一组的加密都依赖前一组的密文
→ 相同的明文产生不同的密文
CTR 模式(计数器):把分组密码当成流密码用,⭐ 可并行。
⭐ GCM 模式(Galois/Counter Mode):CTR + 认证标签。
⭐ 同时提供【机密性】和【完整性】—— 称为 AEAD(带关联数据的认证加密)
→ 这是 TLS 1.3 唯一允许的模式类型(第 28 讲)
📌 现代密码学的一条铁律:**永远不要只加密不认证。**AEAD 把两者绑在一起,从 API 层面消除了「忘了做完整性校验」这类错误。
2.4 对称密钥的根本问题
⭐ Alice 和 Bob 如何在从未见过面的情况下,约定一个只有他们知道的密钥?
**这就是密钥分发问题。**它无法在对称密码的框架内解决——因为约定密钥本身就需要一个安全信道。
三、公钥密码
3.1 突破性思想(Diffie-Hellman, 1976)
每个人有【一对】密钥:
⭐ 公钥 K⁺ —— 公开给所有人
⭐ 私钥 K⁻ —— 只有自己知道
⭐ 关键性质:K⁻(K⁺(m)) = m 且 K⁺(K⁻(m)) = m
而【从公钥无法推算出私钥】
加密:任何人用 Bob 的公钥加密 → 只有 Bob 能用私钥解密。
⭐ 密钥分发问题被解决了:公钥可以公开发布。
3.2 RSA
密钥生成:
① 选两个大素数 p、q
② n = p·q, z = (p−1)(q−1)
③ 选 e,使 1 < e < z 且 ⭐ e 与 z 互质
④ 求 d,使 ⭐ e·d ≡ 1 (mod z)
⑤ 公钥 = (n, e),私钥 = (n, d)
加解密:
加密: c = m^e mod n
解密: m = c^d mod n
3.3 手算示例 ⭐
① p = 5, q = 7
② n = 35, z = 4 × 6 = 24
③ 取 e = 5 (5 与 24 互质 ✓)
④ 求 d 使 5d ≡ 1 (mod 24)
d = 5: 25 mod 24 = 1 ✓
⭐ d = 5
公钥 = (35, 5),私钥 = (35, 5)
加密字母 l(在字母表中是第 12 个):
c = 12^5 mod 35
= 248832 mod 35
248832 ÷ 35 = 7109 余 17
⭐ c = 17
解密:
m = 17^5 mod 35
= 1419857 mod 35
分步计算避免大数:
17^2 = 289; 289 mod 35 = 9
17^4 = 9^2 = 81; 81 mod 35 = 11
17^5 = 11 × 17 = 187; 187 mod 35 = 12
⭐ m = 12 = 'l' ✅
📌 模幂的分步技巧(考试必用):a^b mod n 不要先算 a^b 再取模(数字会爆炸),而要每一步都取模。
3.4 RSA 的安全性基础
⭐ 已知 n,很难分解出 p 和 q(大整数分解问题)
n 为 2048 位时,用已知最好的算法与现有算力,分解需要天文数字的时间
⚠️ 注意措辞是"很难"而不是"不可能"——RSA 的安全性依赖于尚未被证明的计算困难性假设。⭐ Shor 算法证明了量子计算机可以在多项式时间内分解大整数,这就是后量子密码学(PQC)研究的动机。
3.5 ⭐ 为什么必须混合使用
RSA 比 AES 慢【 2–3 个数量级】
因此实际做法(混合加密 / 会话密钥):
① Alice 生成一个【随机的对称会话密钥 K_s】
② ⭐ 用 Bob 的公钥加密 K_s,发给 Bob ← 公钥密码,只用一次
③ Bob 用私钥解出 K_s
④ ⭐ 之后所有数据都用 K_s 做 AES 加密 ← 对称密码,速度快
🎯 这就是 TLS、SSH、PGP 全都采用的模式: 用公钥密码解决"密钥分发",用对称密码解决"批量加密"。各自做自己擅长的事。
四、完整性:哈希、MAC、数字签名
4.1 密码学哈希函数
H(m) → 固定长度的摘要(如 SHA-256 输出 256 位)
三个必需性质:
| 性质 | 含义 |
|---|---|
| 单向性 | 由 H(m) 无法反推出 m |
| 抗第二原像 | 给定 m,找不到 m’ ≠ m 使 H(m’) = H(m) |
| ⭐ 抗碰撞 | 找不到任意一对 m ≠ m’ 使 H(m) = H(m') |
| 算法 | 输出 | 状态 |
|---|---|---|
| MD5 | 128 位 | ⚠️ 碰撞已可在几秒内构造,绝对不可用于安全场景 |
| SHA-1 | 160 位 | ⚠️ 2017 年被 Google 实际构造出碰撞,已淘汰 |
| ⭐ SHA-256 / SHA-3 | 256 位 | ⭐ 当前推荐 |
⚠️ 注意 MD5/SHA-1 仍可用于非安全用途(文件去重、校验传输错误),但任何涉及对手的场景都不能用。
4.2 ⭐ 单独的哈希不能提供完整性
这是一个极其常见的误解。
Alice 发送: (m, H(m))
攻击者截获后: 把 m 改成 m',⭐ 重新计算 H(m'),发送 (m', H(m'))
Bob 验证: H(m') 与收到的一致 ✅ —— 但内容已被篡改
⭐ 因为哈希函数是公开的,任何人都能计算。
解法:加入一个只有双方知道的秘密。
4.3 MAC(报文认证码)
⭐ MAC = H(m + s) s 是双方共享的秘密(认证密钥)
Alice 发送: (m, H(m + s))
攻击者不知道 s → 无法构造合法的 MAC
⭐ 实际使用 HMAC(RFC 2104),它做了两次嵌套哈希:
HMAC(K, m) = H( (K ⊕ opad) ‖ H( (K ⊕ ipad) ‖ m ) )
为什么不用朴素的 H(s‖m)?因为多数哈希函数(MD5、SHA-1、SHA-256)采用 Merkle-Damgård 结构,存在长度扩展攻击:攻击者在不知道 s 的情况下,可以由 H(s‖m) 计算出 H(s‖m‖m')。HMAC 的双层结构消除了这个问题。
4.4 数字签名
MAC 的局限:
⚠️ MAC 用【共享】密钥 → Alice 和 Bob 都能生成
→ Bob 无法向第三方证明"这条消息是 Alice 发的"(他自己也能造)
→ ⭐ 没有【不可否认性】(non-repudiation)
数字签名用私钥:
签名: Alice 用【自己的私钥】加密 H(m) → 签名 σ = K⁻_A(H(m))
验证: 任何人用【Alice 的公钥】解开 σ,与自己算出的 H(m) 比对
⭐ 只有 Alice 有私钥 → 只有 Alice 能签 → Alice 无法否认。
为什么签名 H(m) 而不是 m 本身?
- 性能:公钥运算慢,签 256 位的摘要比签 10 MB 的文件快得多
- 长度:签名长度固定,与消息大小无关
4.5 三者对比 ⭐
| 用什么密钥 | 机密性 | 完整性 | 认证 | 不可否认 | |
|---|---|---|---|---|---|
| 哈希 | 无 | ❌ | ⭐ ❌ | ❌ | ❌ |
| MAC | 共享秘密 | ❌ | ✅ | ✅ | ⭐ ❌ |
| 数字签名 | 私钥 | ❌ | ✅ | ✅ | ⭐ ✅ |
| AEAD(GCM) | 共享秘密 | ✅ | ✅ | ✅ | ❌ |
📌 这张表建议直接背下来,期末必考。
五、公钥分发与证书
5.1 剩下的问题
公钥密码解决了对称密钥的分发问题,但引入了一个新问题:
⭐ 你怎么知道拿到的"Bob 的公钥"真的是 Bob 的?
中间人攻击:
Alice ──"给我 Bob 的公钥"──▶ ⭐ Trudy(冒充)
◀── Trudy 的公钥 K⁺_T ──
Alice 用 K⁺_T 加密 → Trudy 能解密、读取、篡改、再用 K⁺_B 转发给 Bob
⭐ Alice 和 Bob 都以为在安全通信,实际上 Trudy 读了全部内容
5.2 认证中心(CA)与证书
⭐ 证书 = CA 用【自己的私钥】签名的一份声明:
「公钥 K⁺_B 属于 Bob(域名 bob.com)」
任何人用【CA 的公钥】验证签名 → 确认这个绑定是可信的
证书包含:
主体名称(域名)· 主体公钥 · 颁发者 · 有效期
序列号 · 用途扩展 · ⭐ CA 的数字签名
5.3 信任链
⭐ 根 CA(自签名,公钥【预置在操作系统/浏览器中】)
│ 签发
中间 CA
│ 签发
服务器证书(bob.com)
⚠️ 信任的起点必须是「预置的」——根 CA 的公钥不能从网上下载(那又是中间人问题),必须随操作系统或浏览器一起分发。
📌 这意味着一件重要的事:你的浏览器信任着数百个根 CA。任何一个被攻破或作恶,都能为任意域名签发有效证书。
真实案例:
| 年份 | 事件 |
|---|---|
| 2011 | 荷兰 CA DigiNotar 被入侵,攻击者为 *.google.com 签发了有效证书,用于对伊朗用户的大规模中间人攻击。DigiNotar 随后破产 |
| 多次 | 若干 CA 因误签发或流程违规被浏览器厂商吊销信任 |
缓解机制:
- ⭐ 证书透明度(Certificate Transparency, CT):所有签发的证书必须记入公开的、只可追加的日志。域名所有者可以监控是否有人为自己的域名签发了未授权的证书。今天的浏览器要求证书必须有 CT 日志凭据。
- HPKP(公钥固定):已废弃,因为配置错误会让网站永久无法访问——一个"安全机制本身成为可用性风险"的教训。
- CAA 记录(DNS):域名所有者声明"只有 CA X 可以为我签发证书"。
六、认证协议的演进 ⭐
这一节是本讲最好的教学材料:每一版协议都被一种具体的攻击击破,逼出下一版。
ap1.0
Alice ──"我是 Alice"──▶ Bob
⚠️ 任何人都可以这么说。
ap2.0:用 IP 地址认证
Alice ──"我是 Alice"(源 IP = Alice 的 IP)──▶ Bob
⚠️ 被 IP 欺骗击破(第 4 讲)——源地址可以随意伪造。
ap3.0:用密码
Alice ──"我是 Alice" + 密码──▶ Bob
⚠️ 被嗅探击破——密码明文传输,共享介质上任何人都能读到。
ap3.1:加密密码
Alice ──"我是 Alice" + 【加密的】密码──▶ Bob
⚠️ ⭐ 被【重放攻击】击破!
Trudy 不需要【解密】那段密文,
她只需要【原样录下来,下次原样发出去】
→ Bob 解密后得到正确的密码 → 认证通过
📌 这是本讲最重要的一个洞察:**加密不能防重放。**攻击者无需理解内容就能复用它。
ap4.0:引入现时数(Nonce)⭐
⭐ Nonce = 一生只用一次的随机数
Alice ──"我是 Alice"──────────────▶ Bob
◀──── ⭐ 随机数 R ───────────
──── K_{A-B}(R) ───────────▶ Bob 解密,验证得到的是 R
⭐ 为什么能防重放:
R 每次都不同 → 上次录下的 K(R_old) 这次没用
→ 攻击者必须【现场】用密钥加密新的 R,而她没有密钥
🎯 **Nonce 是密码协议中最基本、最重要的构件之一。**你会在 TLS 握手、WPA3、Kerberos、JWT 中反复见到它。
ap5.0:用公钥代替共享密钥
Alice ──"我是 Alice"────────────────▶ Bob
◀──── 随机数 R ───────────────
──── ⭐ K⁻_A(R)(用私钥签名)──▶
◀──── "把你的公钥给我" ────────
──── K⁺_A ──────────────────▶ Bob 验证 K⁺_A(K⁻_A(R)) = R ✓
⚠️ ⭐ 仍然被中间人攻击击破!
Trudy 截获全部通信:
对 Bob 冒充 Alice(用自己的私钥签 R,发自己的公钥)
对 Alice 冒充 Bob
⭐ 双方都认证"成功",但中间坐着 Trudy
⭐ 根本原因:Bob 拿到的"Alice 的公钥"没有经过【认证】
最终解法:证书。Bob 不接受裸公钥,只接受由可信 CA 签名的证书。
演进总结表
| 版本 | 机制 | 被什么击破 |
|---|---|---|
| ap1.0 | 声称身份 | 任何人都能声称 |
| ap2.0 | IP 地址 | IP 欺骗 |
| ap3.0 | 明文密码 | 嗅探 |
| ap3.1 | 加密密码 | ⭐ 重放攻击 |
| ap4.0 | Nonce + 共享密钥 | ✅ 可用,但需要预先共享密钥 |
| ap5.0 | Nonce + 公钥 | ⭐ 中间人攻击 |
| 最终 | Nonce + 公钥 + 证书 | ✅ 这就是 TLS 握手(第 28 讲) |
七、例题(Worked Example)
题目:
(a) RSA:p = 3, q = 11, e = 3。求 n、z、d,并加密 m = 4,再解密验证。 (b) Alice 想向 Bob 发送消息 m,同时保证机密性、完整性、认证和不可否认性。请设计一个方案,写出 Alice 的操作和 Bob 的验证步骤。 (c) 在 (b) 中,如果先加密再签名,与先签名再加密,有什么区别? (d) 为什么单独用哈希不能提供完整性,而 HMAC 可以?
解答:
(a)
n = p·q = 3 × 11 = 33
z = (p−1)(q−1) = 2 × 10 = 20
e = 3 (3 与 20 互质 ✓)
求 d 使 3d ≡ 1 (mod 20):
d=7: 21 mod 20 = 1 ✓
⭐ d = 7
公钥 = (33, 3),私钥 = (33, 7)
加密 m = 4:
c = 4³ mod 33 = 64 mod 33 = ⭐ 31
解密 c = 31:
m = 31⁷ mod 33
分步取模:
31 ≡ −2 (mod 33)
31² ≡ 4 (mod 33)
31⁴ ≡ 4² = 16 (mod 33)
31⁷ = 31⁴ × 31² × 31 ≡ 16 × 4 × 31 (mod 33)
= 64 × 31 ≡ 31 × 31 (mod 33) (64 mod 33 = 31)
= 961 mod 33
961 ÷ 33 = 29 余 4
⭐ m = 4 ✅
(b) 方案:签名 + 混合加密
Alice 的操作:
① 计算摘要: h = H(m) (SHA-256)
② ⭐ 签名: σ = K⁻_Alice(h) → 完整性 + 认证 + 不可否认
③ 生成随机对称会话密钥 K_s
④ ⭐ 加密: c = AES-GCM(K_s, m ‖ σ) → 机密性(+ 传输完整性)
⑤ ⭐ 封装密钥: k = K⁺_Bob(K_s) → 只有 Bob 能取出 K_s
⑥ 发送 (c, k)
Bob 的验证:
① 用私钥解出 K_s = K⁻_Bob(k)
② 用 K_s 解密并验证 GCM 认证标签 → 得到 m 和 σ
③ ⭐ 用 Alice 的【证书中的】公钥验证 σ:K⁺_Alice(σ) 是否等于 H(m)
④ 一致 → 四个属性全部满足 ✅
⚠️ 第 ③ 步必须使用【证书中的】公钥,而不是 Alice 随消息附带的裸公钥——否则就退回到 ap5.0 的中间人问题。
(c) 区别很重要。
⭐ 推荐:先签名再加密(Sign-then-Encrypt),即上面的方案。
先签名再加密:
✅ 签名被加密保护 → ⭐ 第三方无法看到"Alice 给某人发过消息"这一事实
✅ 签名覆盖的是【真正的明文】,语义清晰
先加密再签名:
⚠️ 签名在密文外面,任何人可见 → ⭐ 泄露了通信关系(元数据泄露)
⚠️ 更严重的问题:⭐ 攻击者可以【剥掉 Alice 的签名,换上自己的】,
声称这份密文是【他】发的 —— 这叫"签名剥离攻击"(surreptitious forwarding)
Bob 无法判断真正的作者是谁
📌 一般原则:签名应当覆盖你真正想承诺的内容,而你想承诺的是明文的语义,不是某段密文的字节。
(d)
单独用哈希不行,因为哈希函数是公开的、无密钥的:攻击者把 m 改成 m’ 后,可以自己重新计算 H(m’) 并一并替换,接收方验证会通过。哈希只能检测随机的传输错误,不能对抗有意的篡改。
HMAC 可以,因为它把一个只有通信双方知道的密钥 K 混入了哈希计算:HMAC(K, m)。攻击者不知道 K,因此无法为篡改后的 m’ 生成正确的 HMAC。
⭐ 关键区别是「是否引入了对手不知道的秘密」——这是所有完整性保护机制的共同本质(MAC 用共享秘密,数字签名用私钥)。
八、随堂自测
- 安全通信的四个属性是什么?举一个"有机密性但没有完整性"导致的真实问题。
- ECB 模式为什么不安全?什么是 AEAD?
- 对称密钥密码的根本问题是什么?公钥密码如何解决它?
- RSA:p=7, q=11, e=13,求 d。
- ⭐ 为什么实际系统不直接用 RSA 加密数据?
- ⭐ 为什么单独发送 (m, H(m)) 不能保证完整性?
- MAC 和数字签名的关键区别是什么?哪个提供不可否认性?
- 为什么数字签名要签哈希值而不是原文?
- ⭐ ap3.1 被什么攻击击破?为什么加密不能防这种攻击?
- ap5.0 已经用了公钥和 nonce,为什么还会被中间人攻击?最终怎么解决?
九、本讲要点回顾
- 四个属性:机密性、完整性、认证、可用性——互相独立,缺一不可。⭐ 加密 ≠ 安全。
- ECB 泄露明文结构;⭐ AEAD(AES-GCM)同时提供机密性与完整性,是现代标准。
- 对称密码快但有密钥分发问题;公钥密码解决分发但慢 2–3 个数量级。
- ⭐ 混合加密:公钥加密会话密钥,对称密钥加密数据。TLS/SSH/PGP 都这样做。
- 模幂计算每一步都要取模。
- ⭐ 单独的哈希不提供完整性(哈希是公开的);必须引入对手不知道的秘密。
- MAC(共享秘密)无不可否认性;数字签名(私钥)有。
- 证书 = CA 签名的「公钥属于某主体」的声明;信任起点是预置的根 CA 公钥。
- ⭐ CT(证书透明度) 让误签发可被检测。
- 认证协议演进:ap3.1 被重放击破 → Nonce;ap5.0 被中间人击破 → 证书。
- ⭐ 加密不能防重放——这是本讲最重要的单条洞察。
十、自测答案
1. 机密性、完整性、认证、可用性。真实问题:早期 WEP(第 25 讲)加密了内容但完整性保护极弱(用 CRC-32 而非 MAC),攻击者可以在不解密的情况下翻转密文中的特定比特,造成明文中可预测的改变,并相应修正 CRC——从而在保持"加密"的同时篡改数据包。
2. ECB 对每个分组独立加密,相同的明文分组必然产生相同的密文分组,因此明文的结构完全泄露(著名的"ECB 企鹅"图能透过密文看出原图轮廓)。AEAD(带关联数据的认证加密)指同时提供机密性和完整性/认证的加密模式,如 AES-GCM、ChaCha20-Poly1305;它把加密和认证绑定在一个原语中,从 API 层面杜绝了"只加密忘了认证"这类错误。
3. 根本问题是密钥分发:Alice 和 Bob 若从未见过面,如何约定一个只有他们知道的密钥?在对称密码的框架内这是循环的——约定密钥本身就需要一个安全信道。公钥密码通过一对数学上关联但无法互相推导的密钥解决:公钥可以完全公开发布,任何人用它加密的内容只有私钥持有者能解开,因而无需事先共享任何秘密。
4.
n = 77, z = 6 × 10 = 60
求 d 使 13d ≡ 1 (mod 60)
13 × 37 = 481; 481 mod 60 = 1 ✓
⭐ d = 37
5. 因为 RSA 比 AES 慢 2–3 个数量级(公钥运算涉及大整数模幂)。加密一个几十 MB 的文件用 RSA 在性能上完全不可接受。此外 RSA 每次能加密的数据量受密钥长度限制。因此实际做法是混合加密:用 RSA(或 ECDH)只加密一个短的随机对称会话密钥,之后所有数据都用 AES 加密——公钥密码做密钥分发,对称密码做批量加密。
6. 因为哈希函数是公开的、不含任何秘密。攻击者截获 (m, H(m)) 后,可以把 m 篡改为 m’,然后自己重新计算 H(m’),发送 (m’, H(m’))。接收方的验证会完全通过。裸哈希只能检测随机的传输差错(等价于一个很强的校验和),无法对抗有意的篡改。
7. MAC 使用双方共享的秘密,因此 Alice 和 Bob 都能生成合法的 MAC——Bob 无法向第三方证明某条消息一定是 Alice 发的(他自己也能造一条)。数字签名使用签名者的私钥,只有 Alice 拥有该私钥,因此只有她能生成,任何人都能用她的公钥验证。只有数字签名提供不可否认性(non-repudiation)。
8. 两个原因:① 性能——公钥运算慢,对 256 位的摘要做一次模幂远快于对 10 MB 的原文做运算;② 长度——签名长度固定且很短,与消息大小无关,便于传输和存储。(哈希的抗碰撞性保证了"签摘要"与"签原文"在安全上等价——若攻击者能找到同摘要的另一条消息,那是哈希函数被攻破,而非签名方案的问题。)
9. 被 ⭐ 重放攻击(replay attack) 击破。加密不能防它,是因为攻击者根本不需要理解密文的内容——她只需把那段密文原样录下来,在下一次认证时原样重放。接收方解密后得到的是完全正确的密码,认证通过。这揭示了一个关键认识:加密保护的是"内容不被读懂",而不是"消息不被复用"。防重放需要引入新鲜性(freshness),即 Nonce 或时间戳。
10. 因为 Bob 拿到的"Alice 的公钥"本身没有经过任何认证。攻击者 Trudy 可以同时对两边冒充:对 Bob 出示自己的公钥并声称是 Alice 的(她能用自己的私钥正确签署 Bob 发来的 nonce),对 Alice 同样冒充 Bob。双方的认证都"成功",但所有流量都经过 Trudy。最终解法是证书:Bob 不接受裸公钥,只接受由可信 CA 用其私钥签名的证书,而 CA 的公钥是预置在系统中的(信任的起点不能从网络获取)。这条链条构成的完整协议,就是第 28 讲的 TLS 握手。