1.2 密碼學的基本模型與術語#
典型的保密通信場景#
假設 Alice 要傳訊息給 Bob,路上有竊聽者 Eve。密碼學要解決的核心問題是:如何讓 Eve 讀得到訊息,但看不懂內容。用最通用的模型描述:
明文 M --加密算法E--> 密文 C --解密算法D--> 明文 M
↑金鑰 Ke ↑金鑰 Kd
Eve 竊聽到 C
核心術語表#
| 術語 | 英文 | 說明 |
|---|---|---|
| 明文 | plaintext | 要保護的原始訊息,可以是文字、語音、影像等 |
| 密文 | ciphertext | 加密後看不出意義的訊息 |
| 加密 | encryption | 明文 → 密文 |
| 解密 | decryption | 密文 → 明文 |
| 金鑰 | key | 決定加解密具體行為的祕密參數 |
| 密碼體系 | cipher / cryptosystem | 加密算法 + 解密算法 + 金鑰空間 |
| 編碼 | encoding | 把資料轉為另一種表示(如 Base64),不是加密,無保密作用 |
| 哈希 | hash | 把任意長度資料壓成固定長度指紋,單向、不可逆(第 5 章) |
一個「好的」密文有兩個外觀特徵:看起來像隨機的資料(沒有可辨認的統計規律),且金鑰不同時產生完全不同的密文(雪崩效應)。
兩大分類:對稱式 vs 非對稱式#
- 對稱式加密(symmetric encryption):加密與解密用同一把金鑰(或可互相推導)。代表:AES、ChaCha20。優點是速度快,缺點是必須先解決「金鑰怎麼安全地交給對方」的問題(金鑰配送問題),且 n 個人兩兩通信需要 n(n-1)/2 把金鑰。
- 非對稱式(asymmetric,又稱公開金鑰密碼 public-key cryptography):每人有一對金鑰——公開的「公鑰」與保密的「私鑰」。用公鑰加密的訊息只有對應私鑰能解。代表:RSA、橢圓曲線。解決了金鑰配送問題,並可衍伸出數位簽章,但速度比對稱式慢百倍以上。
實務上兩者合作:非對稱式用來傳對稱金鑰與驗證身分,對稱式用來加密實際資料,這正是 TLS 的架構(9.1 節)。例如你的通訊軟體聊天時,訊息本體幾乎都是 AES 或 ChaCha20 在加密。
密碼學的四大目標#
現代密碼學不只追求「保密」,而是要同時提供四種服務:
- 機密性(confidentiality):只有授權者能讀懂訊息。由加密達成。
- 完整性(integrity):訊息在傳輸或儲存中未被竄改。由 MAC(6.1 節)或簽章達成。注意:加密不等於完整——攻擊者有時能在看不懂的密文上做有效竄改(4.2 節 CBC 的破壞例子)。
- 可驗證性/真實性(authentication):能確認訊息確實來自聲稱的發送者,而非冒名。由數位簽章或 MAC 達成。
- 不可否認性(non-repudiation):發送者事後無法賴帳。只有數位簽章能達成——MAC 不行,因為收發雙方共用同一把金鑰,收方拿著 MAC 值無法向第三人證明是對方算的。
攻擊者的四種模型#
衡量安全前必須先說清楚攻擊者能做什麼。經典分類由弱到強:
- 唯密文攻擊(ciphertext-only):攻擊者只有密文。破解凱薩或維吉尼亞通常在此模型。
- 已知明文攻擊(known-plaintext):攻擊者擁有一些「明文—密文」對。二戰破解 Enigma 大量依賴已知明文(如氣象報告的固定格式)。
- 選定明文攻擊(chosen-plaintext):攻擊者可以任意選明文、拿到對應密文(例如他能把訊息丟進你的加密服務)。現代對稱加密的最低標準是能抵擋此攻擊。
- 選定密文攻擊(chosen-ciphertext):攻擊者可以任意選密文、拿到解密結果(例如重放給解密服務)。最強的模型,公鑰加密系統常採此標準(IND-CCA2)。
設計觀念:安全系統應該在攻擊者能力最強的模型下仍然安全,因為實際世界往往比你想像的更接近選定明文/密文攻擊——雲端服務、自動回覆信件、解密 API 都可能在不知不覺間提供攻擊者這個能力。
對稱加密的數學形式與 Python 示範#
形式化地,一個對稱加密系統是三個函數:
- 密鑰生成
Gen()→ 從金鑰空間均勻選出 K - 加密
Enc(K, M)→ C - 解密
Dec(K, C)→ M
正確性要求:對所有 K、M,Dec(K, Enc(K, M)) == M。
以下示範一個極度簡化的教學用對稱加密(用金鑰字串的重複異或),目的是讓你看到 Gen/Enc/Dec 的骨架;它的安全性極低,將在 3.1 節被「已知明文」輕鬆破解,絕不可用於實務:
import os
import base64
def gen() -> bytes:
return os.urandom(16) # 教學示範:示範「金鑰生成」的骨架
def xor_bytes(a: bytes, b: bytes) -> bytes:
return bytes(x ^ y for x, y in zip(a, b))
def enc(key: bytes, plain: bytes) -> bytes:
# 教學版!重複異或不是安全加密,見 3.1 節的破解
repeated = (key * (len(plain) // len(key) + 1))[: len(plain)]
return xor_bytes(plain, repeated)
def dec(key: bytes, cipher: bytes) -> bytes:
return enc(key, cipher) # XOR 的對稱性:再異或一次即還原
key = gen()
msg = "Hello, 密碼學!".encode("utf-8")
c = enc(key, msg)
print("密文(base64):", base64.b64encode(c).decode())
print("解密還原:", dec(key, c).decode("utf-8"))
assert dec(key, c) == msg
安全性分析#
示範程式碼的正確性成立(能解回原文),但機密性几乎為零:金鑰只有 16 bytes 且重複使用,等於把明文與一個週期性的固定字串異或,統計規律大量洩漏;3.1 節會展示對「重複金鑰異或」的破解。這體現本章最重要的觀念之一:一個系統「能跑」與「安全」是兩回事;判斷安全必須明確列出攻擊者模型、再分析其能力邊界。
練習#
- 執行示範程式,把
enc的輸出連續兩次印出來,觀察同一段明文加密兩次的結果是否相同(重複異或是確定性的):這洩露了什麼?(提示:等長訊息異或兩段密文 = 兩段明文異或)。 - 假設國中把考卷答案用「金鑰異或」加密後上傳到公開網站,而你拿到了另一題的明文與密文對。說明這是哪一種攻擊模型,並寫程式還原完整金鑰。
- 對照四大目標表,說明下列各情境分別需要哪個(或哪些)目標:(a) 網站傳輸密碼 (b) 軟體下載頁的檔案校驗 (c) 電子契約簽署 (d) 通訊軟體讀取回執。