← 返回 Day 148 正文

Day 148 · 图解

Day 148 图解 — 对称与非对称加密

1. 一张图看懂两种加密

┌──────────────────── 对称加密(AES) ────────────────────┐
│                                                          │
│   明文 ──┐                                              │
│          ├──► [ AES 加密 ] ──► 密文 ──► [ AES 解密 ] ──► 明文 │
│   密钥 ──┘         ▲                         ▲         │
│                    └────── 同一把密钥 ────────┘         │
│                                                          │
│   优点: 快(GB/s 级)  缺点: 双方都得有同一把密钥        │
│         ⇒ 密钥怎么安全送到对方手里?(密钥分发难题)       │
└──────────────────────────────────────────────────────────┘

┌──────────────────── 非对称加密(RSA) ──────────────────┐
│                                                          │
│   接收方公钥 ──► [ 公钥加密 ] ──► 密文 ──► [ 私钥解密 ] ──► 明文 │
│                  (谁都能做)              (只有持有者能做) │
│                                                          │
│   优点: 公钥可公开,解决密钥分发  缺点: 慢、有长度上限   │
│   数学基础: 大整数分解难题 (已知 n 难求 p、q)            │
└──────────────────────────────────────────────────────────┘

2. 混合加密 = RSA 送钥匙 + AES 搬货物(TLS 简化流程)

sequenceDiagram participant C as 客户端 participant S as 服务器(公钥/私钥) C->>C: 1. 随机生成会话密钥 K(32 字节) C->>S: 2. RSA_OAEP(服务器公钥, K) C->>S: 3. AES_GCM(K, 业务数据) + nonce C->>S: 4. RSA_PSS(客户端私钥, 密文) 签名 S->>S: 5. 用私钥解出 K S->>S: 6. 验签 → 用 K 解密业务数据 S-->>C: 7. 返回(同样用 K 加密)
sequenceDiagram
    participant C as 客户端
    participant S as 服务器(公钥/私钥)
    C->>C: 1. 随机生成会话密钥 K(32 字节)
    C->>S: 2. RSA_OAEP(服务器公钥, K)
    C->>S: 3. AES_GCM(K, 业务数据) + nonce
    C->>S: 4. RSA_PSS(客户端私钥, 密文) 签名
    S->>S: 5. 用私钥解出 K
    S->>S: 6. 验签 → 用 K 解密业务数据
    S-->>C: 7. 返回(同样用 K 加密)

要点:RSA 只搬运 32 字节的密钥,真正的数据(可能是 GB)永远走 AES。

3. 分组模式:ECB vs CBC vs GCM

明文(16 字节分组): [P1][P2][P3][P4]

ECB(电子密码本)—— ❌ 相同明文块 → 相同密文块,泄露结构!
      [P1]→[C1]  [P2]→[C2]  [P3]→[C1]  [P4]→[C2]
      ECB 加密一张图片后仍能看出轮廓(经典"ECB 企鹅"图)

CBC(密码块链接)—— 需要一个随机 IV,且 IV 不可预测
      前一块密文参与下一块:Ci = E(Pi XOR C(i-1))
      IV: [C1]=E(P1 XOR IV)  [C2]=E(P2 XOR C1)  ...

CTR/GCM(流式 + 认证)—— ✅ 现代推荐
      GCM = CTR 加密 + GHASH 认证标签(AEAD)
      同时保证机密性 + 完整性,nonce 绝不重用

4. AEAD 密文结构(AES-GCM 实际传出的是什么)

 nonce(12B) + ciphertext(与明文等长) + tag(16B)
 ┌────────┬──────────────────────┬──────────────┐
 │ 3f0a…  │  8b2c…(加密后数据) │  认证标签     │
 └────────┴──────────────────────┴──────────────┘
      ▲              ▲                  ▲
   可公开传输    AAD 不参与加密           篡改任何一个字节
               (但参与认证)            都会导致 tag 校验失败

5. RSA 数学直觉(不做公式推导)

密钥生成:
  选两个大素数 p, q        (2048 bit ⇒ p、q 各约 1024 bit)
  n = p * q               (公开)
  φ(n) = (p-1)(q-1)
  选 e(通常 65537)、算 d 使 e*d ≡ 1 (mod φ(n))
  公钥 = (n, e)   私钥 = (n, d)

加密: c = m^e mod n
解密: m = c^d mod n

安全前提: 已知 n 想反推 p、q = 大整数分解难题
  2048-bit 的 n 用目前的计算机分解需要天文数字的时间

⚠️ 但"教科书 RSA"(直接 m^e mod n)不安全:明文 m 很小时可开方还原、 相同明文密文相同。所以工程上必须用 OAEP(加密)/ PSS(签名)填充。

6. 算法选型决策树

需要加密数据?
├─ 数据量 > 几百字节? ──► 是 ──► 混合加密(RSA/ECC 传密钥 + AES 传数据)
├─ 需要证明"是谁发的"/防抵赖? ──► 数字签名(RSA-PSS / ECDSA / Ed25519)
├─ 只需要校验完整性(不需保密)? ──► HMAC / SHA-256
└─ 存密码? ──► 慢哈希加盐(bcrypt/scrypt/Argon2,见 Day 147)