密碼學 - AES
AES (Advanced Encryption Standard) 是目前最廣泛使用的對稱式加密演算法。
在 2001 年由美國國家標準與技術研究院(NIST)正式採用,取代了先前的 DES (Data Encryption Standard),特點是安全性高、運算效率好,且適合硬體實作。
本文將介紹 AES 的基本概念和運作原理,以及在網路安全中的應用。
AES 的原始名稱為 Rijndael 演算法,由比利時密碼學家 Joan Daemen 和 Vincent Rijmen 設計。在經過 NIST 為期 5 年的選拔後,最終在眾多候選人中脫穎而出。
AES 加密的視覺化理解
資料區塊的處理方式
想像一下,如果我們要加密一本書,AES 的處理方式就像是:
分割成固定大小的區塊
- 就像把一本書分成很多個大小相同的紙片
- 每個紙片恰好可以容納 16 個字元(128 位元)
- 最後一片如果不夠 16 個字元,就需要補足(填充 Padding)
狀態矩陣的排列
- 每個區塊被排列成 4×4 的方陣
- 就像把 16 個字元排列成一個四方形的格子
- 這種排列方式有助於後續的數學運算
例如,如果我們要加密 “Hello, World! 123” 這段文字:
加密過程的形象化說明
AES 的加密過程可以比喻成一個多層的料理過程:
SubBytes(位元組替換)
- 就像使用一本密碼本,把每個字母替換成另一個字母
- 這本密碼本(S-box)是經過特殊設計的,確保替換後的結果難以破解
- 例如:’A’ 可能被替換成 ‘R’,’B’ 被替換成 ‘K’ 等
ShiftRows(行移位)
- 像是把每一行向左推動不同的距離
- 第一行不動
- 第二行向左推一格
- 第三行向左推兩格
- 第四行向左推三格
這就像是把一疊撲克牌每一行都錯開一定距離:
1
2
3
4
5
6
7
8
9移位前: A B C D
E F G H
I J K L
M N O P
移位後: A B C D
F G H E
K L I J
P M N OMixColumns(行混合)
- 這步驟像是把每一列的數字放入一個特殊的數學公式中計算
- 可以想像成把四個數字放入一個榨汁機中攪拌
- 輸出的每個數字都受到該列所有數字的影響
AddRoundKey(輪金鑰加)
- 像是把一個金鑰模板覆蓋在結果上
- 每個位置的數值都要和金鑰做數學運算
- 這個步驟確保了沒有金鑰就無法還原資料
加密模式的實際應用
ECB 模式的問題
想像你有一張黑白照片要加密:
- ECB 模式會讓相同的像素值產生相同的加密結果
- 結果就是加密後的圖片仍然可以看出原始圖片的輪廓
- 這就是為什麼 ECB 模式不安全的原因
CBC 模式的運作
就像是製作一條鎖鏈:
- 每個區塊的加密結果會影響下一個區塊
- 如果其中一個環節斷裂(損壞),後面的所有區塊都會受影響
- 這就是為什麼 CBC 模式需要完整的資料才能解密
CTR 模式的特點
可以想像成一個自動產生號碼的加密機:
- 每個區塊都有一個獨特的號碼(計數器)
- 這些號碼經過加密後與原文做運算
- 因為每個區塊使用不同的號碼,所以可以平行處理
GCM 模式的優勢
GCM(Galois/Counter Mode) 是一種結合了加密和驗證的加密模式,提供資料的機密性和完整性保護。GCM 特別適用於需要高效能和安全性的應用場景。
- 機密性與完整性:GCM 不僅加密資料,還產生一個認證標記(Authentication Tag)來確保資料未被篡改。
- 高效能:GCM 支援並行處理,適合在現代多核處理器上運行,提升加密和解密的速度。
- 廣泛應用:被許多現代協定和應用(如 TLS 1.2/1.3、IPsec)採用,成為業界標準。
GCM 的運作步驟:
- 初始化計數器:類似於 CTR 模式,GCM 使用計數器來產生唯一的輸入。
- 加密資料:使用計數器產生的值與原文進行 XOR 運算,實現加密。
- 產生認證標記:在加密過程中,同時計算一個認證標記,用於驗證資料的完整性。
- 傳輸加密資料與認證標記:接收端在解密時驗證認證標記,確保資料未被篡改。
- GCM 是一個強大的加密模式,適合需要同時保護資料機密性和完整性的應用場景。
AES 金鑰長度的詳細說明
考量因素 | AES-128 | AES-192 | AES-256 |
---|---|---|---|
理論安全性 | 17 億億 (2128) 種金鑰組合 | 64 億億 (2192) 種金鑰組合 | 156 億億 (2256) 種金鑰組合 |
效能 | 最高 | 中等 | 較慢 |
安全需求 | 高安全性,廣泛應用,如一般商業應用、移動設備 | 高安全性需求,如金融、醫療資料 | 極高安全性需求,如軍事、政府機構 |
效能需求 | 需要最高運算效率的場景 | 需要較高效能且安全性優先的場景 | 安全性優先,即使有較高運算開銷 |
兼容性 | 廣泛支援於各種系統和協定中 | 多數現代協定和應用支援,但不如 AES-128 廣泛 | 某些系統可能僅支援 AES-128 和 AES-192 |
未來考量 | 足夠應對目前及短期內的安全需求 | 更長期的安全保護需求 | 長期資料保護及抵抗未來可能的攻擊 |
AES-128
- 金鑰長度:128 位元
- 理論安全性:2128 種可能的金鑰組合,目前被認為是非常安全的。
- 安全等級:非常高,對於大多數應用場景來說已經足夠。
- 效能:在硬體和軟體實作中通常具有最高的運算效率。
- 典型使用場景:廣泛應用於商業加密、移動設備和一般用途的加密需求。
AES-192
- 金鑰長度:192 位元
- 理論安全性:2192 種可能的金鑰組合,比 AES-128 更加安全。
- 安全等級:更高,適用於需要更高安全性的應用場景。
- 效能:加密和解密速度略低於 AES-128,但仍然保持良好的效能。
- 典型使用場景:用於對安全性有更高要求的應用,如金融系統和高敏感性資料保護。
AES-256
- 金鑰長度:256 位元
- 理論安全性:2256 種可能的金鑰組合,提供最高的安全等級。
- 安全等級:極高,被認為在未來很長一段時間內都能抵抗暴力破解攻擊。
- 效能:由於金鑰較長,運算開銷相對較高,但現代處理器對 AES-256 有硬體加速支援,效能損失較小。
- 典型使用場景:軍事、政府、極高安全需求的系統,以及需要長期資料保護的應用。
實際應用的案例分析
即時通訊軟體的訊息加密
假設 Alice 要傳送訊息給 Bob:
- Alice 的手機產生一個隨機的 AES 金鑰
- 用這個金鑰加密訊息內容
- 用 Bob 的公鑰加密這個 AES 金鑰
- 把加密後的訊息和加密後的金鑰一起傳送給 Bob
網路銀行的交易加密
當你在網路銀行執行轉帳時:
- 瀏覽器和銀行網站建立 HTTPS 連線
- 使用 AES 加密所有交易資料
- 每個交易階段使用不同的金鑰
- 所有敏感資訊都在加密通道中傳輸
雲端儲存的檔案加密
當你上傳檔案到雲端時:
- 在本地產生唯一的 AES 金鑰
- 用這個金鑰加密檔案內容
- 用你的主金鑰加密這個 AES 金鑰
- 將加密後的檔案和加密後的金鑰上傳到雲端
安全性的具體建議
金鑰管理的最佳實踐
好的金鑰管理就像是管理你的家門鑰匙:
- 不要把鑰匙複製多份到處放
- 定期更換鑰匙
- 妥善保管,不要給未授權的人使用
- 在丟棄舊鑰匙時要確保完全銷毀
IV(初始向量)的使用建議
使用 IV 就像是在密碼上加上日期戳記:
- 每次加密都要使用新的 IV
- IV 可以公開,但不能預測
- IV 的長度必須符合規範
- 確保 IV 的隨機性
錯誤的實作範例
以下是一些常見的錯誤做法:1
2
3
4
5
6
7
8# 錯誤範例 1:使用固定的 IV
iv = b'1234567890123456' # 永遠不要使用固定的 IV!
# 錯誤範例 2:重複使用金鑰和 IV
cipher = AES.new(key, AES.MODE_CBC, iv) # 每次加密都應該用新的 IV
# 錯誤範例 3:使用不安全的金鑰產生方式
key = 'mypassword123'.encode() # 應該使用適當的金鑰產生函數
正確的做法:1
2
3
4
5
6
7
8
9
10
11
12from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
from Crypto.Random import get_random_bytes
# 正確範例 1:使用隨機產生的 IV
iv = get_random_bytes(16)
# 正確範例 2:每次加密都創建新的加密器
cipher = AES.new(key, AES.MODE_CBC, get_random_bytes(16))
# 正確範例 3:使用安全的金鑰產生方式
key = get_random_bytes(32) # 對於 AES-256
結論
選擇適當的金鑰長度需要根據具體的安全需求、效能要求以及系統兼容性來進行權衡:
- AES-128 提供了良好的安全性和效能平衡,適用於大多數商業應用和移動設備。
- AES-192 則適合需要更高安全保護的系統,如金融和醫療資料保護。
- AES-256 為極高安全需求的應用提供了最強的保護,雖然運算開銷較高,但現代硬體的加速支持能夠彌補部分效能損失。
根據您的具體應用場景和需求,選擇最合適的 AES 變體,以確保資料的安全性和系統的效能。
延伸閱讀與資源
官方文件與標準
推薦的加密函式庫
- Python: pycryptodome
- Java: javax.crypto
- C++: Crypto++
- JavaScript: Web Crypto API