對稱加密 vs 非對稱加密:為什麼兩者都需要
1. 為什麼要關心這個問題?
這是一個難題:你想給一個素未謀面的人發送加密訊息,透過一個任何人都可以竊聽的不受信任的網路。
如果你用 AES,你們倆需要相同的金鑰。但你如何安全地共享這個金鑰… 而不需要已經有一個安全通道?
這就是金鑰分發問題,它困擾了密碼學家幾個世紀。解決方案——非對稱加密——從根本上改變了安全通訊的工作方式。但它帶來的權衡意味著我們仍然需要兩種方法。
2. 定義
對稱加密: 雙方使用相同的金鑰進行加密和解密。
- 例子:AES、ChaCha20、3DES
- 類比:一把實體鎖,雙方都有相同的鑰匙
非對稱加密: 每一方都有一個金鑰對——公鑰(可共享)和私鑰(保密)。
- 例子:RSA、ECC、ElGamal
- 類比:有投遞口的信箱——任何人都可以投遞郵件(公鑰),只有主人可以取出(私鑰)
3. 根本區別
對稱:相同的金鑰,相同的問題
Alice Bob
│ │
│ 金鑰: 🔑 │ 金鑰: 🔑
│ │
├──── Encrypt(message, 🔑) ────────────►│
│ 密文 │
│ ├── Decrypt(密文, 🔑)
│ │ = 訊息問題: Alice 和 Bob 是如何都得到金鑰 🔑 的?
- 當面見面?無法擴展。
- 透過網路發送?Eve 會截獲它。
- 使用另一個加密通道?你也需要那個通道的金鑰。
非對稱:不同的金鑰,不同的角色
Alice Bob
│ │
│ 擁有: Bob 的公鑰 📬 │ 擁有: 私鑰 🔐
│ │ 公鑰 📬
│ │
├──── Encrypt(message, 📬) ────────────►│
│ 密文 │
│ ├── Decrypt(密文, 🔐)
│ │ = 訊息解決方案: Bob 公開發布他的公鑰 📬。Eve 可以看到——沒關係!只有 Bob 的私鑰 🔐 能解密用 📬 加密的訊息。
4. 效能:房間裡的大象
非對稱加密解決了金鑰分發問題,但引入了巨大的效能損失。
| 操作 | 對稱 (AES-256) | 非對稱 (RSA-2048) |
|---|---|---|
| 加密速度 | ~1 GB/s | ~1 MB/s |
| 相對速度 | 1x | 慢約 1000 倍 |
| 等效安全性的金鑰大小 | 256 位元 | 2048 位元 |
為什麼非對稱這麼慢?
對稱加密使用簡單操作:互斥或、位元移位、替換表。
非對稱加密使用複雜的數學運算:巨大數字的模冪運算(RSA)或橢圓曲線點乘法(ECC)。
# 對稱:簡單操作重複執行
for round in range(10):
state = substitute(state)
state = shift_rows(state)
state = mix_columns(state)
state = add_round_key(state, key)
# 非對稱:繁重的數學運算
ciphertext = (message ** public_exponent) % modulus
# 其中 modulus 是一個 2048 位元的數字!5. 真實系統:混合加密
現實世界的系統不在對稱和非對稱之間選擇——它們同時使用兩者。
混合方法
┌─────────────────────────────────────────────────────────┐
│ 1. 金鑰交換(非對稱) │
│ - 產生隨機對稱金鑰(工作階段金鑰) │
│ - 用接收者的公鑰加密工作階段金鑰 │
│ - 發送加密後的工作階段金鑰 │
├─────────────────────────────────────────────────────────┤
│ 2. 資料傳輸(對稱) │
│ - 用工作階段金鑰加密實際資料(AES) │
│ - 對大量資料來說快得多 │
└─────────────────────────────────────────────────────────┘TLS 交握範例
用戶端 伺服器
│ │
│ ──── ClientHello ─────────────────────►│
│ │
│ ◄──── ServerHello + 憑證 ──────────── │
│ (包含伺服器公鑰) │
│ │
│ ──── 金鑰交換 ────────────────────────►│
│ (用伺服器公鑰加密) │
│ │
│ ◄════ 加密資料 (AES-GCM) ═════════════►│
│ (使用衍生的工作階段金鑰) │為什麼這樣有效:
- 非對稱加密僅用於金鑰交換一次(或幾次)
- 對稱加密處理大量資料傳輸
- 你得到了兩全其美:安全的金鑰分發 + 快速的資料加密
6. 金鑰分發問題已解決
非對稱密碼學之前(1976年前)
要與 N 個人安全通訊:
- 你需要 N 個不同的對稱金鑰
- 每個金鑰必須安全交換(當面、可信信使)
- 金鑰管理在網路中以 O(N²) 成長
10 人 = 需要 45 個金鑰對
100 人 = 需要 4,950 個金鑰對
1,000 人 = 需要 499,500 個金鑰對非對稱密碼學之後
要與 N 個人安全通訊:
- 每個人有一個金鑰對
- 公鑰可以公開分發
- 金鑰管理以 O(N) 成長
10 人 = 10 個金鑰對
100 人 = 100 個金鑰對
1,000 人 = 1,000 個金鑰對7. 何時使用哪種
在以下情況使用對稱加密:
- 雙方已經共享一個秘密
- 加密靜態資料(檔案、資料庫)
- 需要高效能
- 你控制通訊的兩端
在以下情況使用非對稱加密:
- 各方之前從未通訊過
- 需要數位簽章(不可否認性)
- 分發工作階段金鑰
- 驗證身分(憑證)
在以下情況使用混合:
- 透過不受信任的網路進行安全通訊
- 為他人加密大量資料
- 建構任何現實世界的安全通訊系統
8. 常見誤區
| 誤區 | 現實 |
|---|---|
| 「非對稱比對稱更安全」 | 它們有不同的用途;兩者都可以是安全的 |
| 「什麼都用 RSA 就行」 | RSA 慢約 1000 倍且有大小限制 |
| 「256 位元 AES = 256 位元 RSA 安全性」 | 不對!AES-256 ≈ RSA-15360 的安全等級 |
| 「公鑰可以解密」 | 公鑰加密或驗證;私鑰解密或簽章 |
安全等級對照表
| 對稱 | RSA | ECC |
|---|---|---|
| 80 位元 | 1024 位元 | 160 位元 |
| 128 位元 | 3072 位元 | 256 位元 |
| 256 位元 | 15360 位元 | 512 位元 |
這就是為什麼 ECC 很受歡迎——它用更小的金鑰達到與 RSA 相同的安全性。
9. 程式碼範例:混合加密
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import rsa, padding
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
import os
def hybrid_encrypt(plaintext: bytes, recipient_public_key) -> dict:
# 1. 產生隨機 AES 金鑰(對稱)
aes_key = AESGCM.generate_key(bit_length=256)
# 2. 用 AES 加密資料(快)
nonce = os.urandom(12)
aesgcm = AESGCM(aes_key)
ciphertext = aesgcm.encrypt(nonce, plaintext, None)
# 3. 用 RSA 加密 AES 金鑰(非對稱)
encrypted_key = recipient_public_key.encrypt(
aes_key,
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None
)
)
return {
'encrypted_key': encrypted_key,
'nonce': nonce,
'ciphertext': ciphertext
}
def hybrid_decrypt(encrypted_data: dict, private_key) -> bytes:
# 1. 用 RSA 解密 AES 金鑰
aes_key = private_key.decrypt(
encrypted_data['encrypted_key'],
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None
)
)
# 2. 用 AES 解密資料
aesgcm = AESGCM(aes_key)
plaintext = aesgcm.decrypt(
encrypted_data['nonce'],
encrypted_data['ciphertext'],
None
)
return plaintext10. 本章小結
三點要記住:
對稱快,非對稱解決金鑰分發。 對批量資料使用對稱,對金鑰交換使用非對稱。真實系統兩者都用。
混合方法是標準。 TLS、PGP 以及幾乎所有安全通訊協定都使用非對稱密碼學來交換對稱金鑰。
不同類型的金鑰大小不可比較。 AES-256 提供的安全性大致等於 RSA-15360 或 ECC-512。這就是為什麼 ECC 越來越流行——更小的金鑰,相同的安全性。
11. 下一步
我們多次提到雜湊但沒有完整解釋它。雜湊是加密嗎?(劇透:不是。)
在下一篇文章中,我們將探討:雜湊函式實際上做什麼,為什麼它不是加密,以及儲存密碼的正確方式。
