📑 本页目录(点开跳转)
附录 A · 速查
📌
Ctrl+F搜。不要通读。 用法:写代码或看方案时卡住 → 搜关键词 → 看到那一行 → 回去继续干活。
⭐ 一、只记一页的话,记这个
| 场景 | 用这个 | 别用 |
|---|---|---|
| 对称加密 | AES-256-GCM / ChaCha20-Poly1305 | ECB、CBC 无 MAC、任何裸流密码 |
| 口令 → 密钥 | Argon2id(退路 scrypt / PBKDF2) | MD5、SHA-256 单次、口令直接当密钥 |
| 哈希 | SHA-256 / SHA-3 / BLAKE2 | MD5、SHA-1 |
| 消息认证 | HMAC-SHA256 | 自造的 H(key‖msg) |
| 签名 | Ed25519 | 教科书 RSA、无 PSS 的 RSA |
| 密钥交换 | X25519(+ ML-KEM 混合) | 无认证的裸 DH |
| 随机数 | secrets / os.urandom |
random ⭐ |
| 比较 MAC | hmac.compare_digest |
== ⭐ |
🔑 一条压倒一切的原则: 用成熟库的高层 API(如
cryptography的 Fernet / AEAD),不要自己拼装。 本教程 24 章的结论几乎都指向这一句。
🧭 二、「我该翻哪一章」
| 你的问题 | 去哪 |
|---|---|
| 加密到底保护什么、不保护什么 | 01 |
| 为什么不能自己发明密码 | 02 |
| 什么叫"绝对安全"、为什么不实用 | 03 |
| 随机数为什么这么重要 | 04 ⭐ |
| nonce 能不能重复 | 05 ⭐ |
| AES 内部怎么工作 | 06 |
| 该用哪个工作模式 | 07 ⭐ |
| "安全"到底怎么定义 | 08 |
| 哈希该选哪个、能防什么 | 09 |
为什么不能用 H(key‖msg) |
10 ⭐ |
| 加密了还要不要认证 | 11 ⭐ |
| 怎么证明"某条数据在集合里" | 12 |
| RSA 的数学基础 | 13 |
| RSA 怎么用才安全 | 14 |
| 双方怎么协商出密钥 | 15 |
| 为什么现在都用椭圆曲线 | 16 |
| 签名怎么选、k 值为什么致命 | 17 ⭐ |
| 证书和 HTTPS 怎么回事 | 18 |
| 密钥该怎么存、怎么轮换 | 19 ⭐ |
| 区块链用了哪些密码学 | 20 |
| 怎么证明我知道但不说出来 | 21 ⭐ |
| 加密后还能不能计算 | 22 |
| 量子来了怎么办 | 23 ⭐ |
💀 三、致命错误清单(按出现频率排)
| # | 错误 | 后果 | 章 |
|---|---|---|---|
| 1 | nonce/IV 重复 | GCM 直接泄露认证密钥;流密码明文异或 | 05、07 |
| 2 | 只加密不认证 | 可被篡改、填充预言攻击 | 11 |
| 3 | 用 random 生成密钥 |
可预测,直接被算出来 | 04 |
| 4 | 口令直接当密钥 | 暴力破解成本从年降到秒 | 19 |
| 5 | H(key‖msg) 当 MAC |
长度扩展攻击可伪造 | 10 |
| 6 | == 比较 MAC |
时序攻击逐字节猜出 | 11、24 |
| 7 | ECDSA 的 k 重复/可预测 | 私钥直接泄露 | 17 |
| 8 | 教科书 RSA(不填充) | 存在性伪造、同态伪造 | 14 |
| 9 | 认证失败仍输出部分明文 | 变成解密预言机 | 07、24 |
| 10 | 证书验证漏检 CA:TRUE / 域名 | 任意证书可冒充任意站点 | 18 |
| 11 | 分块加密不认证顺序 | 可重排、可截断 | 24 |
| 12 | 同一密钥多用途 | 上下文混淆,互相打穿 | 17、19 |
📐 四、核心公式与结论
生日界(碰撞概率)
$$\text{n 位哈希,约 } 2^{n/2} \text{ 次尝试后出现碰撞}$$
- SHA-256 → 2¹²⁸ ✅
- 随机 96 位 nonce → 约 2⁴⁸ 条消息后有碰撞风险 ⭐(GCM 的实际约束)
RSA
$$c = m^e \bmod n,\quad m = c^d \bmod n,\quad ed \equiv 1 \pmod{\varphi(n)}$$
⚠️ 必须用 OAEP(加密)/ PSS(签名),教科书版本不安全。
Diffie–Hellman
$$A = g^a,\; B = g^b \;\Longrightarrow\; \text{共享} = g^{ab}$$
⚠️ 无认证 ⟹ 中间人。必须配签名/证书(第 18 章)。
ECDSA 的 k 重复 💀
$$k = \frac{H_1-H_2}{s_1-s_2},\qquad d = \frac{s_1k - H_1}{r}$$
✅ 用 RFC 6979 确定性 k,或直接用 Ed25519。
Schnorr / 零知识
$$t=g^r,\quad c=H(m\|t),\quad s=r+cx,\quad \text{验证 } g^s \stackrel{?}{=} t\cdot y^c$$
⭐ 同一个 t 答两个挑战 ⟹ $x=\frac{s_1-s_2}{c_1-c_2}$(知识提取=私钥泄露,一体两面)
Mosca 定理(后量子迁移)
$$x(保密年限)+ y(迁移年限)> z(距量子机年数)\;\Longrightarrow\; \text{现在就晚了}$$
🔑 五、密钥长度对照(2025)
| 安全等级 | 对称 | RSA | 椭圆曲线 | 后量子 |
|---|---|---|---|---|
| 128 位 | AES-128 | 3072 | 256(P-256/X25519) | ML-KEM-768 |
| 192 位 | AES-192 | 7680 | 384 | ML-KEM-1024 |
| 256 位 | AES-256 ⭐ | 15360 | 521 | ML-DSA-87 |
💡 注意 RSA 那一列增长得多离谱 —— 这就是椭圆曲线取代它的原因。
⚛️ 六、量子影响速查
| 算法 | 影响 | 对策 |
|---|---|---|
| RSA / DH / ECC | 💀 Shor 完全破解 | 换 ML-KEM / ML-DSA |
| AES-128 | ⚠️ Grover 减半→64 位 | 换 AES-256 |
| AES-256 | ✅ 基本无影响 | 不动 |
| SHA-256/3 | ✅ 基本无影响 | 不动 |
🔑 对称加倍长度即可,公钥必须换算法。
🧰 七、Python 速查
# ---- 随机 ----
import secrets
key = secrets.token_bytes(32) # ✅ 不要用 random
# ---- 口令 → 密钥 ----
from argon2.low_level import hash_secret_raw, Type
k = hash_secret_raw(pwd, salt, time_cost=3, memory_cost=65536,
parallelism=4, hash_len=32, type=Type.ID)
# ---- 认证加密(推荐入口)----
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
aes = AESGCM(key)
nonce = secrets.token_bytes(12) # ⭐ 每次都要新的
ct = aes.encrypt(nonce, plaintext, aad) # aad 放文件头/上下文
pt = aes.decrypt(nonce, ct, aad) # 失败抛异常 → 整体失败
# ---- 最省心的对称加密 ----
from cryptography.fernet import Fernet
f = Fernet(Fernet.generate_key()) # ⭐ 帮你处理好了模式/nonce/认证
# ---- 签名 ----
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
sk = Ed25519PrivateKey.generate()
sig = sk.sign(b"msg")
sk.public_key().verify(sig, b"msg")
# ---- 比较 MAC / token ----
import hmac
hmac.compare_digest(a, b) # ✅ 绝不要用 ==
📖 八、术语对照
| 中文 | 英文 | 一句话 |
|---|---|---|
| 保密性 | Confidentiality | 别人看不到内容 |
| 完整性 | Integrity | 内容没被改 |
| 认证性 | Authenticity | 确实是他发的 |
| 不可否认 | Non-repudiation | 他事后赖不掉(只有签名能给) |
| 前向保密 | Forward Secrecy | 长期密钥泄露也解不了旧流量 |
| 随机预言机 | Random Oracle | 把哈希理想化成随机函数的证明模型 |
| 归约 | Reduction | 把"破解方案"变成"解决数学难题" |
| 语义安全 | Semantic Security | 密文不泄露明文的任何信息 |
| 选择密文攻击 | CCA | 攻击者能拿到任意密文的解密结果 |
| 可延展性 | Malleability | 能在不解密的情况下有意义地改密文 |
| 陷门函数 | Trapdoor Function | 正向易、反向难,除非有陷门 |
| 认证加密 | AEAD | 同时提供保密+完整+关联数据认证 |
| 密钥派生 | KDF | 从口令或主密钥导出工作密钥 |
| 信封加密 | Envelope Encryption | 主密钥包裹数据密钥 |
| 密码学敏捷性 | Crypto-agility | 能换算法而不用重写系统 ⭐ |
| 知识提取 | Extraction | 从能作答者身上"抠出"秘密 |
| 毒废料 | Toxic Waste | 可信设置里必须销毁的随机数 |
🚨 九、事故名册(每个都值得记住)
| 事故 | 根因 | 章 |
|---|---|---|
| PlayStation 3 越狱 | ECDSA 的 k 写成常数 | 17 |
| Android 比特币钱包被盗 | SecureRandom 缺陷 → k 重复 |
04、17 |
| DigiNotar 破产 | CA 被入侵,签发假 *.google.com | 18 |
| Flame 恶意软件 | MD5 碰撞伪造微软签名 | 09 |
| Heartbleed | 越界读(不是密码学,是内存安全) | — |
| KRACK(WPA2) | 重放握手导致 nonce 重用 | 05 |
| Debian OpenSSL (2008) | 熵源被误删 → 密钥空间只剩 32768 个 | 04 ⭐ |
| SIKE 被击破 | 后量子候选,笔记本一小时破 | 23 |
| DAO 重入 | 智能合约 bug(不是密码学) | 20 |
| 比特币交易延展性 | 签名可延展(非 SUF-CMA) | 17 |
🔑 看这张表最该注意的一点: 绝大多数事故的根因,都不是"数学被破解"。 是随机数、是 nonce、是少做一次检查、是内存安全、是合约逻辑。 这是整本教程最重要的一条结论。
👉 回到首页