计算机网络原理
第八章 第2节
第八章第二节:认证、数字签名、CA、TLS
1. 认证:为什么一版一版都失败?
认证的目标是:
Bob 要确认:对面真的是 Alice,而不是 Trudy 假扮的。
1.1 ap1.0:只说“我是 Alice”
Alice → Bob: I am Alice
失败原因很简单:
Trudy 也可以说:I am Alice
所以“声明身份”不等于“证明身份”。
1.2 ap2.0:加上 Alice 的 IP 地址
Alice → Bob: I am Alice + Alice 的 IP 地址
看起来更可信,但还是失败。
因为 Trudy 可以伪造一个分组,让里面写着 Alice 的 IP 地址。
核心问题:
IP 地址可以被伪造,不能单独作为身份证明。
1.3 ap3.0:发送密码
Alice → Bob:
Alice 的 IP 地址 + Alice 的 password + I am Alice
这能证明 Alice 知道密码,但问题更大:
密码直接在网络上传,Trudy 可以窃听。
一旦 Trudy 录下来,以后也能发同样的内容。
这就是重放攻击 replay attack
意思是:
攻击者不一定知道密码含义,只要把之前录下来的合法报文再发一次,也可能骗过 Bob。
1.4 ap3.0 升级:发送“加密后的密码”
Alice → Bob:Alice 的 IP 地址 + encrypted password + I am Alice
这比明文密码好,但仍然挡不住重放攻击。
因为 Trudy 可以录下:
Alice 的 IP 地址 + encrypted password + I am Alice
以后直接重放。
Bob 看到的还是一个合法格式的报文。
所以问题不是“密码有没有加密”,而是:
Bob 怎么知道这次认证是新的,不是旧报文重放?
2. nonce:解决重放攻击
nonce 是:协议中只使用一次的随机数 R
2.1 ap4.0:对称密钥 + nonce
前提:Alice 和 Bob 事先共享一个对称密钥 K_AB
认证过程:
1. Alice → Bob: I am Alice
2. Bob → Alice: R
3. Alice → Bob: K_AB(R)
含义:
Bob 生成一个新随机数 R。
Alice 用双方共享的密钥 K_AB 加密 R。
Bob 自己也能算 K_AB(R),如果对得上,就认为对方知道 K_AB。
为什么能防重放?
因为每次 Bob 发的 R 都不同。
旧的:K_AB(R_old)
不能用来回答新的:K_AB(R_new)
所以 Trudy 录旧报文也没用。
2.2 ap4.0 的缺点
ap4.0 需要 Alice 和 Bob 事先共享密钥。
问题是:如果世界上每两个人通信前都要提前共享一个密钥,管理太麻烦。
所以引入公钥体系。
其实还有一些缺点,我们自我思考
如果Trudy 不只是偷听,还能主动转发。
流程可以变成:
1. Trudy → Bob: I am Alice
2. Bob → Trudy: R_new
3. Trudy → Alice: R_new
4. Alice → Trudy: K_AB(R_new)
5. Trudy → Bob: K_AB(R_new)
这样 Bob 会以为 Trudy 是 Alice。
中继攻击 / 实时转发攻击 / 中间人攻击
所以 ap4.0 的能力边界是:
能防旧报文重放,不能防 Trudy 实时拿 Bob 的题去问 Alice
3. ap5.0:公钥认证
思想:
只有 Alice 有 Alice 的私钥。
如果 Alice 能用自己的私钥处理 Bob 给的 nonce R,
Bob 再用 Alice 的公钥验证成功,
就说明对方确实拥有 Alice 的私钥。
过程:
1. Alice → Bob: I am Alice
2. Bob → Alice: R
3. Alice → Bob: K_A^-(R)
4. Bob 用 Alice 的公钥 K_A^+ 验证:
K_A^+(K_A^-(R)) = R
这里:
K_A^-:Alice 的私钥
K_A^+:Alice 的公钥
4. ap5.0 的安全漏洞:中间人攻击
ap5.0 看起来很完美,但有一个大漏洞:
Bob 怎么确定他拿到的公钥真的是 Alice 的公钥?
Trudy 可以站在 Alice 和 Bob 中间:(也就是我刚刚那个猜想)
Alice ←→ Trudy ←→ Bob
Trudy 对 Bob 假装自己是 Alice。 Bob 问:“把你的公钥给我。” Trudy 把自己的公钥发给 Bob,并说:这是 Alice 的公钥
Bob 如果相信了,就会用 Trudy 的公钥验证,结果 Trudy 当然能通过。
所以公钥体系的关键问题是:公钥本身也需要认证。
公钥不是拿到了就能信,必须证明“这个公钥真的属于 Alice”。
5. 数字签名
数字签名类似手写签名,但更强。
它解决两个问题:
1. 认证:这个消息确实是 Bob 发的
2. 完整性:消息没有被改过
5.1 直接签名报文
Bob 对报文 m 签名:签名 = K_B^-(m)
Alice 收到:m 和 K_B^-(m)
然后用 Bob 的公钥验证:
K_B^+(K_B^-(m)) = m ?
如果成立,说明:只有拥有 Bob 私钥的人才能产生这个签名。
因此可以证明:这个报文确实由 Bob 签名。
5.2 为什么不能直接签整个大报文?
因为公钥加密运算很慢。
如果 m 是很长的邮件、文件、网页内容,直接对 m 做 RSA 签名很费时间。
所以实际不签整个 m,而是先做摘要。
6. 报文摘要 hash
hash 函数 H 的作用是:
把任意长度的报文 m
变成固定长度的摘要 H(m)
比如:
很长的文件 m
↓ H
固定长度摘要 H(m)
这个摘要也叫:fingerprint 指纹
6.1 好的 hash 函数要满足什么?
1. 多对一
2. 输出固定长度
3. 单向性:给 H(m),很难反推出 m
4. 抗碰撞:很难找到两个不同 m 和 m',使 H(m)=H(m')
注意,“多对一”是数学上必然的,因为:
输入空间无限大,输出长度固定。
所以理论上一定存在碰撞。安全要求是:攻击者很难故意构造碰撞。
6.2 Internet 校验和为什么弱?
Internet checksum 也是一种“摘要”,但它太弱。
不同报文
得到相同校验和
这说明它适合“偶然错误检测”,不适合“安全完整性保护”。
7. 数字签名 = 对报文摘要签名
真正常用做法:
1. Bob 计算 H(m)
2. Bob 用自己的私钥签名 H(m)
signature = K_B^-(H(m))
3. Bob 发送:
m + signature
Alice 收到后:
1. 对收到的 m 重新计算 H(m)
2. 用 Bob 的公钥解开签名:
K_B^+(signature)
3. 比较两个值是否相等
也就是比较:
H(m) ?= K_B^+(K_B^-(H(m)))
如果相等:
1. 报文没被改
2. 签名确实来自 Bob
8. CA:公钥认证中心
前面 ap5.0 的问题是:
我怎么知道这个公钥真的是 Bob 的?
CA 就是解决这个问题的。
CA 全称:Certificate Authority
公钥认证中心
它的作用是:把“身份”和“公钥”绑定起来。
8.1 证书是什么?
证书 certificate 里面大概包含:
1. 实体身份信息:这是 Bob
2. Bob 的公钥 K_B^+
3. CA 的数字签名
CA 用自己的私钥签名:
CA 签名 = K_CA^-(Bob 的身份信息 + Bob 的公钥)
所以证书的含义是:
CA 证明:这个公钥确实属于 Bob。
8.2 Alice 如何验证 Bob 的证书?
过程:
1. Alice 拿到 Bob 的证书
2. Alice 用 CA 的公钥 K_CA^+ 验证 CA 的签名
3. 验证成功后,Alice 相信证书里的 Bob 公钥是真的
关键问题:
Alice 为什么信 CA 的公钥?
因为浏览器、操作系统里内置了一批根 CA 的公钥。
8.3 信任树
信任链大概是:
操作系统/浏览器信任根 CA
根 CA 签发中间 CA
中间 CA 签发网站证书
浏览器验证这条链
所以访问 HTTPS 网站时,本质上浏览器在确认:
这个网站给我的公钥,确实属于这个网站。
9. Diffie-Hellman:共享密钥协商
DH 解决的问题是:
Alice 和 Bob 没有提前见过,
怎么在不直接发送密钥的情况下,协商出同一个共享密钥?
它和 RSA 不一样。RSA 是公钥加密算法,DH 是密钥协商算法。
9.1 DH 的基本步骤
公开参数:
大素数 p
生成元 g
Alice 选择私有随机数:S_A
Bob 选择私有随机数:S_B
Alice 公开:
K_A^+ = g^{S_A} mod p
Bob 公开:
K_B^+ = g^{S_B} mod p
Alice 计算共享密钥:
(K_B^+)^{S_A} mod p
= (g^{S_B})^{S_A} mod p
= g^{S_A S_B} mod p
Bob 计算共享密钥:
(K_A^+)^{S_B} mod p
= (g^{S_A})^{S_B} mod p
= g^{S_A S_B} mod p
所以双方算出来一样。
9.2 DH 的关键优点
Alice 和 Bob 没有直接在网络上传共享密钥。
网络上传的是:
g
p
g^{S_A} mod p
g^{S_B} mod p
攻击者看到了这些,也很难算出:
g^{S_A S_B} mod p
9.3 DH 也需要认证
单独的 DH 仍然可能被中间人攻击。
因为 Trudy 可以分别和 Alice、Bob 做 DH:
Alice ←→ Trudy
Trudy ←→ Bob
最后 Alice 以为自己和 Bob 共享密钥,Bob 也以为自己和 Alice 共享密钥,但实际上中间是 Trudy。
所以真实系统中:DH + 证书 / 数字签名一起用。
10. 安全电子邮件
安全电子邮件要同时满足:
1. 机密性
2. 完整性
3. 源端认证
10.1 只保证机密性
Alice 给 Bob 发机密邮件。
做法:
1. Alice 生成随机对称密钥 K_S
2. 用 K_S 加密邮件 m,得到 K_S(m)
3. 用 Bob 的公钥加密 K_S,得到 K_B^+(K_S)
4. Alice 发送:
K_S(m) + K_B^+(K_S)
Bob 收到后:
1. 用自己的私钥解开 K_B^+(K_S),得到 K_S
2. 用 K_S 解密 K_S(m),得到 m
为什么不用 Bob 公钥直接加密 m?
因为:公钥加密慢,对称加密快。
所以实际还是:
公钥加密负责传会话密钥
对称加密负责加密正文
10.2 保证完整性和可认证性
Alice 先对邮件 m 做 hash:
H(m)
然后用自己的私钥签名:
K_A^-(H(m))
Alice 发送:
m + K_A^-(H(m))
Bob 收到后:
1. 对 m 重新算 H(m)
2. 用 Alice 公钥解开签名
3. 比较两个 H(m)
如果相等,Bob 知道:
1. 邮件没有被改
2. 邮件确实由 Alice 签名
10.3 同时保证三者
最终组合:
Alice 使用:
1. 自己的私钥 K_A^-:做数字签名
2. Bob 的公钥 K_B^+:加密会话密钥
3. 新生成的对称密钥 K_S:加密邮件正文
对应功能:
K_A^-:认证 + 完整性
K_B^+:安全传递会话密钥
K_S:高效保证机密性
签名用发送者私钥,加密会话密钥用接收者公钥,正文加密用临时对称密钥。
11. TLS:传输层安全
TLS 用在 HTTPS 里面。
它的目标是:
让 TCP 连接变安全。
普通 TCP 只负责可靠传输,不负责安全。TLS 加在 TCP 上面,让应用层看到的是安全连接。
TLS 提供:
1. 机密性
2. 完整性
3. 认证
12. TLS 的整体流程
1. 握手
2. 密钥导出
3. 数据传输
4. 连接关闭
12.1 握手阶段

主要做三件事:
1. Alice 和 Bob 建立 TCP 连接
2. Alice 验证 Bob 的身份
3. 双方协商出后续通信需要的密钥
Bob 会给 Alice:
Bob 的证书 certificate
Alice 用 CA 公钥验证证书,确认:
Bob 的公钥确实属于 Bob。
然后双方生成主密钥:MS = master secret
12.2 密钥生成阶段
不能所有用途都用同一把密钥。原因:
同一把密钥既加密又做 MAC,不安全。
所以 TLS 会从主密钥 MS 派生出多把密钥。
四把:
K_C:client → server 的加密密钥
M_C:client → server 的 MAC 密钥
K_S:server → client 的加密密钥
M_S:server → client 的 MAC 密钥

一个方向一套密钥;
加密和完整性校验也分开。
12.3 数据传输阶段:为什么要分 record?
TCP 是字节流。
问题是:
如果把整个 TCP 字节流最后才做一次 MAC,
那接收方要等全部数据收完,才能检查完整性。
这不现实。所以 TLS 把数据切成一个个 record。
每个 record 里面:
data + MAC
然后整体加密:K_C(data, MAC)
其中:MAC = H(data + M_C)
接收方解密后:
1. 拿到 data 和 MAC
2. 用同一个 M_C 重新计算 MAC
3. 比较是否一致
如果一致,说明:
1. data 没被改
2. data 确实来自知道 M_C 的对方

13. MAC:报文认证码
MAC 全称:Message Authentication Code
它不是 MAC 地址。这里的 MAC 是安全里的:报文认证码
作用:检查完整性 + 证明对方知道共享密钥
基本形式:MAC = H(message + shared_secret)

H(m + M_C)
其中:
m:报文
M_C:共享的 MAC 密钥
13.1 MAC 和数字签名的区别
对比 | MAC | 数字签名 用什么密钥 | 共享密钥 | 私钥 / 公钥 谁能生成 | 共享密钥双方都能生成 | 只有私钥拥有者 谁能验证 | 共享密钥双方 | 任何有公钥的人 是否能向第三方证明 | 不能 | 可以 速度 | 快 | 慢
所以:
MAC:适合通信双方之间快速验证
数字签名:适合公开证明身份和不可否认
14. 回顾
只说身份
↓
加 IP
↓
加密码
↓
加密密码
↓
nonce 防重放
↓
公钥认证
↓
发现公钥也可能被冒充
↓
CA 认证公钥
↓
数字签名保证身份和完整性
↓
DH/TLS 协商会话密钥
↓
用对称密钥高速加密真实数据
15.三组概念
15.1 加密 和 签名
加密:为了不让别人看懂
签名:为了证明是谁发的,以及没被改
加密:
用接收方公钥加密
接收方用自己的私钥解密
签名:
发送方用自己的私钥签名
接收方用发送方公钥验证
15.2 hash 和 MAC 和 数字签名
hash:只生成摘要,本身没有密钥,不能证明身份。
MAC:hash 中加入共享密钥,可以证明对方知道密钥。
数字签名:用私钥签名 hash,可以公开验证身份。
15.3 RSA 和 DH 和 AES
AES:对称加密,快,用来加密大量数据。
RSA:公钥加密/签名,慢,用来加密会话密钥或做签名。
DH:密钥协商,不直接加密正文,用来双方算出共享密钥。
16. 总结
1. nonce 是一次性随机数,用来防止重放攻击。
2. 认证不是“我说我是 Alice”,而是证明自己拥有某个秘密。
3. 对称密钥认证需要双方预共享密钥。
4. 公钥认证需要保证公钥本身可信,否则会被中间人攻击。
5. CA 通过证书把身份和公钥绑定。
6. 数字签名 = 对报文摘要用私钥签名。
7. hash 用来生成固定长度摘要,但普通 checksum 太弱。
8. MAC = 带密钥的摘要,用于完整性和认证。
9. TLS = 握手认证 + 密钥协商 + record 加密传输 + MAC 完整性保护。
10. 实际系统一般用公钥体系协商密钥,再用对称密钥加密大量数据。
