Appearance
密码学基础
概念
上一章讲的分布式系统,所有协调都建立在"消息可以被偷看、被篡改、被冒充"的信道上。密码学要解决的正是这件事:在一个谁都能监听的信道上,让两个陌生人安全地说话。
它有三类目标,需要分清楚:
| 目标 | 回答什么问题 | 手段 |
|---|---|---|
| 机密性(confidentiality) | 别人看不懂 | 加密 |
| 完整性(integrity) | 内容有没有被改过 | 哈希、MAC、签名 |
| 认证(authentication) | 对面到底是谁 | 签名、证书、口令 |
关键认知:这三件事不能用一个手段全包。加密过的数据照样可能被篡改(只是改了之后解出来是垃圾),哈希能查改但不能保密——"加密 + 认证"要一起做,这也是为什么现代协议都用 AEAD(带认证的加密)。
原理
一、两类钥匙:对称与非对称
| 对称加密 | 非对称加密(公钥) | |
|---|---|---|
| 钥匙 | 同一把(或能互相推出) | 一对:公钥加密 / 私钥解密 |
| 速度 | 快(比非对称快 2~3 个数量级) | 慢 |
| 密钥分发 | 难(怎么把钥匙给对面) | 公钥可公开广播 |
| 代表 | DES、3DES、AES | RSA、DH、ECC |
| 主要用途 | 传数据 | 协商密钥、签名 |
实战里的做法是"混合加密":用非对称算法传一把临时对称密钥,然后用对称算法传数据。非对称只做"小任务"——因为慢,也因为它的数学结构只适合处理短消息。
对称算法本身:DES 密钥只有 56 位(已被穷举击穿)→ 3DES 只是过渡 → AES 是现在的标准(128 / 192 / 256 位),分组 128 位。
二、分组密码的工作模式:ECB 为什么不能直接用
分组密码一次只能处理一个固定长度的块。块与块怎么串起来,就是工作模式:
| 模式 | 做法 | 问题 / 用途 |
|---|---|---|
| ECB | 每块独立加密 | 相同明文块得到相同密文块,图案原样泄漏,除加密随机密钥外不要用 |
| CBC | 每块先与前一块密文异或再加密 | 需要 IV;能隐藏图案;错误会向后传播 |
| CTR | 把分组密码当流密码用(加密计数器再异或) | 可并行、可随机访问;绝不能重用计数器 |
| GCM | CTR + 认证标签 | AEAD:一次给出机密性与完整性,现代首选 |
ECB 的病灶用一句话说清:它的加密是"逐块独立的函数",所以相等的输入必然给出相等的输出——而"哪两块相同"本身就是要保密的信息。
三、非对称加密:三个数学难题
| 算法 | 依赖的难题 | 用途 |
|---|---|---|
| RSA | 大整数分解(给定 n = p·q,分解出 p、q) | 加密、签名 |
| Diffie-Hellman | 有限域上的离散对数 | 只做密钥协商,不加密数据 |
| ECC | 椭圆曲线上的离散对数 | 加密、签名(密钥更短) |
RSA 的机制(下面示例会完整算一遍):
- 选两个大素数 p、q,算出 n = p·q(公开)与 φ(n) = (p−1)(q−1)(保密)
- 选 e 与 φ(n) 互素,公开 (e, n) 作为公钥
- 求 d ≡ e⁻¹ (mod φ(n)),藏起来 (d, n) 作为私钥
- 加密 c = m^e mod n,解密 m = c^d mod n
安全性全部落在那一步:攻击者知道 n,但要从 n 反推出 φ(n),就必须分解 n——大数分解没有已知的多项式时间算法。
Diffie-Hellman 是另一条路:双方各选一个私密指数,交换 g 的幂,各自算出同一个共享密钥,而这个密钥从未在信道上出现过。
四、哈希:单向、抗碰撞、雪崩
| 性质 | 含义 |
|---|---|
| 单向性(抗原像) | 给定摘要,反推原文不可行 |
| 抗弱碰撞(抗第二原像) | 给定原文,找不到另一段有相同摘要的输入 |
| 抗强碰撞 | 找不到任意两段不同的输入有相同摘要 |
| 雪崩效应 | 输入改 1 位,输出约一半的位翻转 |
生日攻击是最容易被忽略的一条:找碰撞不需要试 2^b 次,只要约 1.18·2^(b/2) 次。b 位哈希的碰撞安全性只有 b/2 位:
| 哈希长度 | 50% 碰撞所需尝试 | 意味 |
|---|---|---|
| 32 位 | ≈ 7.7 万次 | 秒破 |
| 64 位 | ≈ 5.1 × 10⁹ 次 | 单机仍可行 |
| 128 位(MD5) | ≈ 2.2 × 10¹⁹ 次 | 暴力不可行,但已被密码分析击穿 |
| 160 位(SHA-1) | ≈ 1.4 × 10²⁴ 次 | 2017 年已被实际构造出碰撞 |
| 256 位(SHA-256) | ≈ 4.0 × 10³⁸ 次 | 当前安全底线 |
注意最后两行:MD5 与 SHA-1 的失守不是因为算力够大了,而是数学上被找到了捷径——这是"设计缺陷"而不是"长度不够"。
五、MAC 与数字签名:都要"防篡改",分工不同
| MAC(消息认证码) | 数字签名 | |
|---|---|---|
| 用什么 | 对称密钥(双方共享) | 私钥签 / 公钥验 |
| 谁能生成 | 双方都会 | 只有私钥持有者 |
| 谁能验证 | 只有持有密钥的双方 | 任何人(公钥公开) |
| 能证明"是谁发的"吗 | 不能(双方都能造) | 能(不可否认) |
| 速度 | 快 | 慢 |
一句话:MAC 证明"消息没被外人改",签名证明"消息是某个人发的"。 需要事后追责(如电子合同)时必须用签名。
六、证书与 PKI:把公钥和身份绑起来
公钥是公开的,可"这个公钥真的属于这个网站吗"?攻击者完全可以把自己的公钥发给你。
证书 = 权威机构(CA)对"公钥 + 身份信息"的签名。校验链是:
- 浏览器内置若干根 CA 的公钥
- 服务器给出自己的证书链,最后能追到某个根 CA
- 逐级用上一级的公钥验下一级的签名,一直验到根
- 再检查证书里的域名是否匹配、是否在有效期内
链条的锚点是浏览器内置的根 CA——所以"根 CA 私钥泄露"是灾难级事件。
七、口令存储:绝不能存明文,也别只加一次哈希
| 做法 | 安全性 |
|---|---|
| 存明文 | 最坏,一次泄露全暴露 |
| 存 MD5/SHA-1 | 坏:彩虹表可反查,且 GPU 每秒能算几十亿次 |
| 存 SHA-256 无盐 | 仍坏:相同口令得到相同摘要,可批量比对 |
| 加盐 + 慢哈希 | 正确做法 |
加盐(salt):每个用户一个随机串,跟口令拼在一起再哈希,存在库里。它让"相同的口令得到不同的摘要",彩虹表立刻失效。
慢哈希:bcrypt / scrypt / Argon2 故意把计算变慢(并可调内存开销)。"慢"是特性不是缺点——攻击者要试几十亿次,慢 1 万倍就等于代价涨 1 万倍。
示例
例 1:模幂的代价——RSA 为什么不能"硬算"(C)
RSA 的核心运算是 m^e mod n。如果老老实实连乘 e−1 次,e 一变大(实际是 65537)就慢得不能用。标准做法是平方-乘(从左到右扫指数的二进制位)。
#include <stdio.h>
typedef unsigned long long u64;
/* n 只有 3233 的量级,所以 a*b 用 64 位乘法不会溢出 */
static u64 mulmod(u64 a, u64 b, u64 n) { return a * b % n; }
/* 平方-乘:每移一位就平方一次,遇到 1 再乘一次 */
static u64 powmod(u64 base, u64 exp, u64 n, int *sq, int *ml) {
u64 r = 1;
base %= n;
*sq = 0;
*ml = 0;
while (exp) {
if (exp & 1u) { r = mulmod(r, base, n); (*ml)++; }
exp >>= 1;
if (exp) { base = mulmod(base, base, n); (*sq)++; }
}
return r;
}
int main(void) {
const u64 n = 3233, e = 17, d = 2753; /* 由 p=61、q=53 生成 */
int sq, ml;
u64 ms[4] = {65, 72, 85, 100};
printf("%-6s %-8s %-8s %-4s\n", "m", "c", "back", "ok");
for (int i = 0; i < 4; i++) {
u64 c = powmod(ms[i], e, n, &sq, &ml);
u64 back = powmod(c, d, n, &sq, &ml);
printf("%-6llu %-8llu %-8llu %-4s\n", ms[i], c, back,
back == ms[i] ? "OK" : "BAD");
}
powmod(65, e, n, &sq, &ml);
printf("powmod(e=%llu): %d squarings + %d multiplies = %d mulmods\n",
e, sq, ml, sq + ml);
printf("straight multiply: %llu mulmods -> save %.1f%%\n",
e - 1, 100.0 * (e - 1 - (sq + ml)) / (e - 1));
return 0;
}
c 本站为静态站,不提供在线运行;可复制到本地用 gcc / python 执行
预期输出:
m c back ok
65 2790 65 OK
72 3000 72 OK
85 2310 85 OK
100 1773 100 OK
powmod(e=17): 4 squarings + 2 multiplies = 6 mulmods
straight multiply: 16 mulmods -> save 62.5%读数:e = 17 = 10001₂,4 次平方 + 2 次相乘 = 6 次模乘,而硬算要 16 次,省 62.5%。实际的 e 是 65537(也是"平方-乘友好"的形状),省下的倍数还要大得多。
注意四行 OK:加密再解密回到原文,这才是"这套参数可用"的证明——参数错了(比如 e 与 φ(n) 不互素)这一步立刻暴露。
例 2:RSA、DH、生日攻击、雪崩、ECB(Python)
C 段只算了模幂。这里把剩下的账一次算清:完整的 RSA 流程、DH 密钥交换、等效强度表、生日攻击门槛、雪崩效应、以及 ECB 与 CBC 的差别。
import hashlib
def pad(s, w):
dw = sum(2 if ord(c) > 0x2000 else 1 for c in str(s))
return str(s) + " " * max(0, w - dw)
def table(head, rows, gap=2):
data = [[str(c) for c in r] for r in rows]
w = [max([sum(2 if ord(c) > 0x2000 else 1 for c in str(head[i]))]
+ [sum(2 if ord(c) > 0x2000 else 1 for c in r[i]) for r in data]) + gap
for i in range(len(head))]
print(" " + "".join(pad(head[i], w[i]) for i in range(len(head))))
for r in data:
print(" " + "".join(pad(r[i], w[i]) for i in range(len(head))))
print("=== 1. 小整数 RSA:从选素数到加解密全流程 ===")
P, Q = 61, 53
n = P * Q
phi = (P - 1) * (Q - 1)
e = 17
def egcd(a, b):
if b == 0:
return a, 1, 0
g, x, y = egcd(b, a % b)
return g, y, x - (a // b) * y
g, x, _ = egcd(e, phi)
d = x % phi
print(" p=%d q=%d -> n=%d(模数,公开) phi(n)=%d(必须保密)" % (P, Q, n, phi))
print(" 公钥指数 e=%d -> 私钥指数 d=%d(e·d mod phi = %d)" % (e, d, e * d % phi))
print(" 公开 (e,n)=(%d,%d),藏起来 (d,n)=(%d,%d)" % (e, n, d, n))
rows = []
for m in (65, 72, 85, 100):
c = pow(m, e, n)
back = pow(c, d, n)
rows.append(["%d" % m, "%d" % c, "%d" % back, "OK" if back == m else "FAIL"])
table(["明文 m", "密文 c = m^e mod n", "解回 m^d mod n", "往返"], rows)
print(" 注意:n=3233 只有 12 位二进制,实际要 2048 位以上 —— 上面这套只是算术演示,强度为零。")
print()
print("=== 2. Diffie-Hellman 密钥交换:双方从不传输密钥本体 ===")
p, gg = 23, 5
a, b = 6, 15
A = pow(gg, a, p)
B = pow(gg, b, p)
ka = pow(B, a, p)
kb = pow(A, b, p)
rows = [["公开", "p = %d(模数),g = %d(生成元)" % (p, gg)],
["A 私藏", "a = %d" % a],
["B 私藏", "b = %d" % b],
["A 发出", "A = g^a mod p = %d" % A],
["B 发出", "B = g^b mod p = %d" % B],
["A 算出的钥匙", "B^a mod p = %d" % ka],
["B 算出的钥匙", "A^b mod p = %d" % kb]]
table(["角色", "数值"], rows)
print(" 两把钥匙相等(%d)—— 窃听者只在线上见到 p、g、%d、%d,要靠解离散对数才能反推出 a、b。"
% (ka, A, B))
print()
print("=== 3. 等效强度:多大密钥的 RSA 才顶得上 AES-128 ===")
rows = [
["80", "1024", "160", "已不推荐"],
["112", "2048", "224", "2026 年主流下限"],
["128", "3072", "256", "与 AES-128 同级"],
["256", "15360", "512", "与 AES-256 同级"],
]
table(["对称密钥(位)", "RSA(位)", "ECC(位)", "备注"], rows)
print(" 公钥算法“密钥更短、等效强度却更高”是 ECC 的全部卖点:2048 位 RSA ↔ 224 位 ECC,差 9.1 倍。")
print()
print("=== 4. 生日攻击:为什么'哈希输出一半位数'就够了 ===")
rows = []
note = {32: "秒破", 64: "单机仍可行", 128: "不可行(但已被密码分析击穿)",
160: "不可行(2017 年已被构造出碰撞)", 256: "当前安全底线"}
for bits in (32, 64, 128, 160, 256):
k = 1.1774 * (2 ** (bits / 2))
rows.append(["%d 位" % bits, "%.3e" % (2 ** bits), "%.4e" % k, note[bits]])
table(["哈希长度", "空间大小 2^b", "50% 碰撞所需 ≈1.18·2^(b/2)", "说明"], rows)
print(" 只需 2^(b/2) 次,不是 2^b 次:32 位哈希撞到 50% 只要约 7.7 万次。")
print(" 更狠的是'碰撞'不必暴力搜:MD5 早在 2004 年就被密码分析击穿(代价远低于 2^64),")
print(" SHA-1 也在 2017 年被 Google 与 CWI 实际构造出碰撞。所以现在哈希起步就是 SHA-256。")
print()
print("=== 5. 雪崩效应:改 1 个比特,输出变一半 ===")
base = b"hello world"
h0 = hashlib.sha256(base).hexdigest()
rows = []
for pos in (0, 1, 2):
m = bytearray(base)
m[pos] ^= 0x01
h1 = hashlib.sha256(bytes(m)).hexdigest()
dist = bin(int(h0, 16) ^ int(h1, 16)).count("1")
rows.append(["第 %d 字节翻最低位" % (pos + 1), m.decode(), "%d / 256" % dist,
"%.1f%%" % (100.0 * dist / 256)])
table(["改动", "变后的明文", "汉明距离", "翻转比例"], rows)
print(" 理想值 50%(128/256),三次实测都在 48.8%~49.2% —— 输入变 1 位,输出像换了个随机数。")
print(" 这正是哈希能当'完整性指纹'的根据:改动必然被发现。")
print()
print("=== 6. 分组密码两种工作模式:ECB 为什么不能直接用 ===")
def toy_block(pt, key):
"""玩具'分组密码':SHA-256(块 || 密钥) 截前 4 字节,只为演示工作模式的差别"""
return hashlib.sha256(pt + key).digest()[:4]
KEY = b"\x5a" * 4
iv = b"\x3c" * 4
plain = bytes([0x11, 0x22, 0x33, 0x44, 0x11, 0x22, 0x33, 0x44, 0x99, 0x00, 0x00, 0x01])
blocks = [plain[i:i + 4] for i in range(0, len(plain), 4)]
ecb = b"".join(toy_block(b, KEY) for b in blocks)
out, prev = [], iv
for b in blocks:
c = toy_block(bytes(x ^ y for x, y in zip(b, prev)), KEY)
out.append(c)
prev = c
cbc = b"".join(out)
rows = []
for i, b in enumerate(blocks):
rows.append(["第 %d 块" % (i + 1), b.hex(" "), ecb[i * 4:i * 4 + 4].hex(" "),
cbc[i * 4:i * 4 + 4].hex(" ")])
table(["分组", "明文块", "ECB 密文块", "CBC 密文块"], rows)
print(" ECB 下第 1 块与第 2 块明文相同(11 22 33 44),密文也完全相同 —— 图案原样泄漏。")
print(" CBC 下同样的两块密文不同,因为后一块混进了前一块的密文 —— 这就是'链'的作用。")
print(" 实战结论:ECB 除了加密随机密钥,别的场景都不要用;要认证还要用 GCM 这类 AEAD 模式。")
python 本站为静态站,不提供在线运行;可复制到本地用 gcc / python 执行
预期输出:
=== 1. 小整数 RSA:从选素数到加解密全流程 ===
p=61 q=53 -> n=3233(模数,公开) phi(n)=3120(必须保密)
公钥指数 e=17 -> 私钥指数 d=2753(e·d mod phi = 1)
公开 (e,n)=(17,3233),藏起来 (d,n)=(2753,3233)
明文 m 密文 c = m^e mod n 解回 m^d mod n 往返
65 2790 65 OK
72 3000 72 OK
85 2310 85 OK
100 1773 100 OK
注意:n=3233 只有 12 位二进制,实际要 2048 位以上 —— 上面这套只是算术演示,强度为零。
=== 2. Diffie-Hellman 密钥交换:双方从不传输密钥本体 ===
角色 数值
公开 p = 23(模数),g = 5(生成元)
A 私藏 a = 6
B 私藏 b = 15
A 发出 A = g^a mod p = 8
B 发出 B = g^b mod p = 19
A 算出的钥匙 B^a mod p = 2
B 算出的钥匙 A^b mod p = 2
两把钥匙相等(2)—— 窃听者只在线上见到 p、g、8、19,要靠解离散对数才能反推出 a、b。
=== 3. 等效强度:多大密钥的 RSA 才顶得上 AES-128 ===
对称密钥(位) RSA(位) ECC(位) 备注
80 1024 160 已不推荐
112 2048 224 2026 年主流下限
128 3072 256 与 AES-128 同级
256 15360 512 与 AES-256 同级
公钥算法“密钥更短、等效强度却更高”是 ECC 的全部卖点:2048 位 RSA ↔ 224 位 ECC,差 9.1 倍。
=== 4. 生日攻击:为什么'哈希输出一半位数'就够了 ===
哈希长度 空间大小 2^b 50% 碰撞所需 ≈1.18·2^(b/2) 说明
32 位 4.295e+09 7.7162e+04 秒破
64 位 1.845e+19 5.0569e+09 单机仍可行
128 位 3.403e+38 2.1719e+19 不可行(但已被密码分析击穿)
160 位 1.462e+48 1.4234e+24 不可行(2017 年已被构造出碰撞)
256 位 1.158e+77 4.0065e+38 当前安全底线
只需 2^(b/2) 次,不是 2^b 次:32 位哈希撞到 50% 只要约 7.7 万次。
更狠的是'碰撞'不必暴力搜:MD5 早在 2004 年就被密码分析击穿(代价远低于 2^64),
SHA-1 也在 2017 年被 Google 与 CWI 实际构造出碰撞。所以现在哈希起步就是 SHA-256。
=== 5. 雪崩效应:改 1 个比特,输出变一半 ===
改动 变后的明文 汉明距离 翻转比例
第 1 字节翻最低位 iello world 126 / 256 49.2%
第 2 字节翻最低位 hdllo world 125 / 256 48.8%
第 3 字节翻最低位 hemlo world 125 / 256 48.8%
理想值 50%(128/256),三次实测都在 48.8%~49.2% —— 输入变 1 位,输出像换了个随机数。
这正是哈希能当'完整性指纹'的根据:改动必然被发现。
=== 6. 分组密码两种工作模式:ECB 为什么不能直接用 ===
分组 明文块 ECB 密文块 CBC 密文块
第 1 块 11 22 33 44 ee 06 f2 ba 9a 83 ad 68
第 2 块 11 22 33 44 ee 06 f2 ba ec 16 fd 1f
第 3 块 99 00 00 01 ed 3b 1b d9 a0 71 19 da
ECB 下第 1 块与第 2 块明文相同(11 22 33 44),密文也完全相同 —— 图案原样泄漏。
CBC 下同样的两块密文不同,因为后一块混进了前一块的密文 —— 这就是'链'的作用。
实战结论:ECB 除了加密随机密钥,别的场景都不要用;要认证还要用 GCM 这类 AEAD 模式。四条结论:
- RSA 的四个数都能手算:n = 3233、φ(n) = 3120、e = 17、d = 2753,且
17 × 2753 mod 3120 = 1。四组明文全部往返成功——"能解回来"就是参数正确的证明。 - DH 的共享密钥是"算出来的"而不是"传过去的":线上只出现 p、g、8、19,双方各自算出 2。窃听者要拿到 2,只能解离散对数。
- 生日攻击把碰撞门槛砍到一半位数:32 位哈希要 7.7 万次、64 位要 50.6 亿次。这也是"摘要长度要长于安全强度需求的两倍"的由来。
- ECB 泄漏"哪些块相同":第 1、2 块明文一样,密文就一模一样;CBC 靠"链"把相同的块岔开了。
考点
考点
1. 三个目标与它们的手段
| 目标 | 手段 | 说明 |
|---|---|---|
| 机密性 | 对称 / 非对称加密 | 只管"看不懂" |
| 完整性 | 哈希 / MAC / 签名 | 只管"没被改" |
| 认证 | 签名 / 证书 / 口令 | 只管"是谁" |
加密不等于认证:只加密不认证,攻击者可以翻转密文位来可控地改明文(CBC 的位翻转攻击)。现代做法是 AEAD(如 GCM)。
2. 对称 vs 非对称
- 对称快、密钥分发难;非对称慢、公钥可公开。
- 实战用混合加密:非对称只用来协商会话密钥。
- DH 只能协商密钥,不能加密数据;用它加密是常见错误。
3. RSA 的机制与数字例子
- n = p·q 公开,φ(n) = (p−1)(q−1) 保密;
e·d ≡ 1 (mod φ(n))。 - 小例子:p=61, q=53 → n=3233, φ=3120, e=17, d=2753。
- 安全性 = 大数分解困难;签名与加密是同一套运算,方向相反(私钥加密 = 签名)。
- e 常取 65537:二进制 1 0000 0000 0000 0001,平方-乘只需 17 次模乘。
4. 哈希与生日攻击(高频)
- 碰撞安全性只有一半位数:b 位哈希只需 ≈ 1.18·2^(b/2) 次。
- 32 位 → 7.7 万次;64 位 → 50.6 亿次;128 位(MD5)已被密码分析攻破。
- MD5 / SHA-1 的失守是设计缺陷,不是长度不够;现用最少 SHA-256。
- 雪崩:改 1 位 → 约一半输出位翻转;用它验证实现是否正确。
5. MAC vs 签名
| MAC | 签名 | |
|---|---|---|
| 密钥 | 对称(共享) | 非对称 |
| 谁能生成 | 双方 | 只有私钥持有者 |
| 可否否认 | 可以(双方都能造) | 不可以 |
| 性能 | 快(如 HMAC-SHA256) | 慢 |
要"追责/不可否认"就必须用签名,MAC 做不到。
6. 口令存储
- 绝不能存明文,也不能只存一次 SHA/MD5(彩虹表 + GPU 穷举)。
- 加盐让相同口令得到不同摘要;慢哈希(bcrypt / scrypt / Argon2)让每次尝试都变贵。
- 口令不是加密后存起来再解出来比对的——只做"重新哈希后比对摘要"。
7. 易错点清单
- 认为"加密了就安全":没有完整性保护的密文可以被篡改。
- 用 ECB 加密有结构的数据:图案泄漏。
- 把哈希当加密:哈希不可逆,不能"解回原文"。
- 认为 MD5 只是"短了点":它是被找到了碰撞构造方法。
- 在 CBC 里重用 IV、在 CTR/GCM 里重用计数器:两者都会直接泄漏明文异或关系。
- 用同一个 RSA 密钥既签名又加密:应分密钥使用。
- 自己设计密码算法或"加点混淆":密码学的第一原则是不要自创。
- 把"密钥长度"直接当"等效强度"比:RSA-2048 ≈ 112 位对称强度,不是 2048 位。
小结
- 密码学解决的是"在不安全信道上建立信任":机密性靠加密、完整性靠哈希/MAC/签名、认证靠签名与证书——三件事要分别满足,不能互相替代。
- 对称快、非对称能分发密钥,所以实战是混合加密;DH 只协商密钥,不加密数据。
- RSA 的安全性等价于大数分解困难;
e·d ≡ 1 mod φ(n)与"加解密互逆"是它的全部算术骨架。 - 哈希只有一半位数的碰撞安全性(生日攻击),而且 MD5 / SHA-1 是被数学击穿的——长度够不等于设计对。
- MAC 与签名的分界是"能不能否认";口令存储的正确姿势是加盐 + 慢哈希。
回到主线:这一章和 内存一致性模型 讲的"多核之间不共享真相"是同一件事的两端——前者解决"怎么让多台机器达成一致",后者解决"怎么确认消息没被改、说话人没被冒充"。往下走,消息要真正在物理世界里跑起来,靠的是 计网的物理层 与 采样与调制——即"信号怎么承载比特"。soft 分支 14 篇到此全部收口。
下一篇:信号与系统基础
评论(0)
当前浏览器不允许本地存储,评论无法保存。
还没有评论,来说两句。