# 【密碼學 VII - Advanced Encryption Standard】 ## 01. AES 簡介與發展歷史 ### 01-01. 背景與需求 * **前身問題**:隨著運算能力的飛速進步,過去廣泛使用的 **DES (Data Encryption Standard)** 因其僅有 **56-bit** 的金鑰長度,已變得脆弱且容易受到**暴力破解攻擊 (Brute-force attacks)**。因此,美國國家標準技術研究所 (NIST) 於 1997 年發起公開徵選,尋求下一代的加密標準。 ### 01-02. 徵選過程與決選 NIST 對於新標準 (後來命名為 AES) 提出了明確要求: * **區塊長度**:必須支援 **128 bits** 的明文區塊。 * **金鑰長度**:必須支援 **128、192 和 256 bits** 三種長度。 * **公開性**:演算法必須是公開可取得的。 **歷程節點**: 1. **1997年**:公開徵求提案。 2. **1998年8月 (第一階段)**:從 21 個提案中選出 15 個候選演算法。 3. **1999年9月 (第二階段)**:選出 5 個決選名單 (Finalists):MARS、RC6、**Rijndael**、Serpent、Twofish 4. **2000年10月**:NIST 宣布由比利時研究員 **Joan Daemen** 與 **Vincent Rijmen** 設計的 **Rijndael** (發音近似 "Rain Doll") 獲選為 AES。 5. **2001年12月**:正式發布為聯邦資訊處理標準 **FIPS 197**。 ### 01-03. 評選標準 (Evaluation Criteria) NIST 評估候選演算法的三大核心指標: * **安全性 (Security)**:抵抗密碼分析攻擊的能力。 * **成本 (Cost)**:運算效率與記憶體需求。 * **實作性 (Implementation)**:在不同硬體與軟體環境下的適應性。 <br> ## 02. AES 的回合與金鑰架構 (Rounds & Keys) ![截圖 2025-11-20 凌晨2.02.06](https://hackmd.io/_uploads/rJKQ8FsgZx.png) ### 02-01. 非 Feistel 架構 與 DES 不同,AES 採用的是 **Non-Feistel** 架構。這意味著 AES 在每一回合中,會對整個資料區塊進行並行處理,而非像 Feistel 架構那樣將資料切半處理。 ### 02-02. 回合數與金鑰長度的關係 AES 處理的資料區塊固定為 **128 bits**,但運算的回合數 ($N_r$) 取決於金鑰長度: | AES 版本 | 金鑰長度 (Cipher Key) | 回合數 ($N_r$) | | :--- | :--- | :--- | | AES-128 | 128 bits | 10 | | AES-192 | 192 bits | 12 | | AES-256 | 256 bits | 14 | :::info **注意事項**:雖然輸入的「加密金鑰 (Cipher Key)」長度不同 (128/192/256),但在每一回合運算中使用的「**回合金鑰 (Round Keys)**」長度始終固定為 **128 bits**。 ::: ## 03. 資料單位與狀態矩陣 (Data Units & State) ![截圖 2025-11-20 凌晨2.02.17](https://hackmd.io/_uploads/HymN8YjeZe.png) AES 的運算核心在於將一維的位元流轉換為二維的矩陣進行操作。 ### 03-01. Block 與 State 的轉換 ![截圖 2025-11-20 凌晨2.02.26](https://hackmd.io/_uploads/Sy24LFox-g.png) **Block (區塊)**:輸入的原始資料,為 128 bits 的線性序列 (16 bytes)。 * **序列表示**:$b_0, b_1, b_2, \dots, b_{15}$ **State (狀態矩陣)**:AES 內部運算使用的 $4 \times 4$ byte 矩陣。 * **填充規則**:採用**直行優先 (Column-Major Order)**。即先填滿第一行 (Column 0),再填第二行,依此類推。 ### 03-02. 轉換範例 (Changing Plaintext to State) ![截圖 2025-11-20 凌晨2.02.38](https://hackmd.io/_uploads/B1dSUKox-x.png) :::success **重點筆記**:假設明文 (Plaintext) 為文字 `"AES USE HEX MATR"` (剛好 16 個字元)。 - 對應的十六進位碼假設為:`41 45 53 20 55 53 45 20 48 45 58 20 4D 41 54 52` - **輸入陣列 ($b_0 \dots b_{15}$)**:`b0=41`, `b1=45`, `b2=53`, `b3=20`, `b4=55` ... - **轉換為 State 矩陣 ($s_{row, col}$)**:注意觀察 $b_0$ 到 $b_3$ 是填在第一行,$b_4$ 到 $b_7$ 填在第二行。 \begin{bmatrix} s_{0,0} & s_{0,1} & s_{0,2} & s_{0,3} \\ s_{1,0} & s_{1,1} & s_{1,2} & s_{1,3} \\ s_{2,0} & s_{2,1} & s_{2,2} & s_{2,3} \\ s_{3,0} & s_{3,1} & s_{3,2} & s_{3,3} \end{bmatrix} \begin{bmatrix} 41 & 55 & 48 & 4D \\ 45 & 53 & 45 & 41 \\ 53 & 45 & 58 & 54 \\ 20 & 20 & 20 & 52 \end{bmatrix} 1. $b_0 (41)$ 在 $(0,0)$ 2. $b_1 (45)$ 在 $(1,0)$ 3. $b_4 (55)$ 在 $(0,1)$ ← 注意這裡換到了第二行 ::: <br> ## 04. 加密端的回合結構概觀 (Structure of Each Round) 在加密過程中,AES 的回合結構包含四種變換的組合,但在**第一回合之前**與**最後一回合**有特殊的處理: ![截圖 2025-11-20 凌晨2.02.49](https://hackmd.io/_uploads/Sk8UIKieZe.png) - **初始變換 (Pre-round Transformation)**:僅執行 **AddRoundKey** (加入回合金鑰)。 - **標準回合 (Rounds 1 to $N_r - 1$)**:**SubBytes** (位元組代換)、**ShiftRows** (列位移)、**MixColumns** (行混合)、**AddRoundKey** (加入回合金鑰) - **最終回合 (Round $N_r$)**:**SubBytes**、**ShiftRows**、**AddRoundKey**、(注意:最終回合移除了 MixColumns 步驟) <br> ## 05. 四大運算變換 (Transformations) 為了提供安全性,AES 採用了四種不同類型的變換技術,分別對應:取代 (Substitution)、排列 (Permutation)、混合 (Mixing) 以及加入金鑰 (Key-adding)。 ### 05-01. SubBytes (位元組代換) **功能**:這是一個針對每個 Byte 獨立進行的非線性變換,也是 AES 與 DES 類似的「取代」步驟。 **操作細節**: * 將輸入的 Byte 視為兩個十六進位數字 (例如 `0C`) 進行查表。 * 這涉及 16 個獨立的 Byte-to-Byte 變換。 * **可逆性**:此變換是可逆的 (Invertible),解密時使用 `InvSubBytes` 即可還原。 ![截圖 2025-11-20 凌晨2.05.52](https://hackmd.io/_uploads/ByJfvKoe-g.png) :::success **重點筆記**:利用查表法得出 SubBytes ![截圖 2025-12-09 晚上10.58.42](https://hackmd.io/_uploads/rkTQtnHMWe.png) ![截圖 2025-11-20 凌晨2.06.04](https://hackmd.io/_uploads/rJPGDKoxbe.png) ::: **數學定義 ($GF(2^8)$ 體)**: * 除了查表法,SubBytes 也可以用代數方式定義。 * 基於 $GF(2^8)$ 有限域,使用不可約多項式 (Irreducible polynomial):$m(x) = x^8 + x^4 + x^3 + x + 1$。 * **運算公式**: 1. $d = X(s_{r,c})^{-1} \oplus y$。先求出該 Byte 在 $GF(2^8)$ 的**乘法反元素** (Multiplicative Inverse),再進行仿射變換 (Affine Transformation)。 2. $[X^{-1}(d \oplus y)]^{-1} = [X^{-1}(X(s_{r,c})^{-1} \oplus y \oplus y)]^{-1} = [(s_{r, c}^{-1})]^{-1} = s_{r, c}$ ![截圖 2025-11-20 凌晨2.06.30](https://hackmd.io/_uploads/ByGEvYixbx.png) :::success **重點筆記**:`0C` 如何透過 `SubBytes` 變換為 `FE`,以及如何透過 `InvSubBytes` 完美還原。 1. **SubBytes (加密過程)**:`SubBytes` 的運算包含兩個步驟:首先求出該數值在有限域中的乘法反元素,接著進行仿射變換 (Affine Transformation)。 **Step 1: 求乘法反元素 (Multiplicative Inverse)** * 在 $GF(2^8)$ 有限域中,輸入值 `0C` 的乘法反元素為 **`B0`**。 * 將 `B0` 轉換為二進位向量 $b$:$$b = (10110000)_2$$ **Step 2: 仿射變換 (Affine Transformation)** * **矩陣乘法**:將向量 $b$ 乘以固定的轉換矩陣 $X$,得到中間值 $c$。 $$c = X \times b = (10011101)_2$$ * **XOR 常數運算**:將 $c$ 與固定的常數向量 $y$ 進行 XOR 運算 ($d = c \oplus y$)。 $$d = (11111110)_2$$ * **最終結果**:二進位 `11111110` 轉換為十六進位即為 **`FE`**。 2. **InvSubBytes (解密過程)**:解密過程是上述步驟的逆運算,順序相反。 **Step 1: 逆仿射變換 (Inverse Affine Transformation)** * **XOR 逆運算**:輸入密文 `FE`,先進行 XOR 運算移除常數項,還原出中間值 $c$。 $$c = (10011101)_2$$ * **逆矩陣乘法**:將 $c$ 乘以逆矩陣 $X^{-1}$。 $$b = X^{-1} \times c = (11010000)_2$$ * 此結果即為十六進位的 **`B0`**。 **Step 2: 求乘法反元素** * 求出 `B0` 在 $GF(2^8)$ 中的乘法反元素。 * 其結果即為原始輸入 **`0C`**。 ::: **SubBytes 之 Pseudocode** ```python= SubBytes(S) { for(r = 0 to 3) for(c = 0 to 3) Sr,c = subbyte(Sr,c) } subbyte(byte) { a <- byte^(-1) ByteTOMartrix(a, b) for(i = 0 to 7) { c_i <- b_i XOR b_{(i+4) mod 8} XOR b_{(i+5) mod 8} XOR b_{(i+6) mod 8} XOR b_{(i+7) mod 8} d_i <- c_i XOR ByteToMatrix (0x63) } MatrixToByte(d, d) byte <- d } ``` ### 05-02. ShiftRows (列位移) **功能**:提供排列 (Permutation) 效果。 **操作細節**: * **加密 (Encryption)**:執行**向左位移 (Shift Left)**。 * **解密 (Decryption)**:執行 `InvShiftRows`,即**向右位移 (Shift Right)**。 **位移規則**:位移的 Byte 數取決於列編號 (Row Number)。 * 第 0 列:不移動。 * 第 1 列:移動 1 Byte。 * 第 2 列:移動 2 Bytes。 * 第 3 列:移動 3 Bytes。 ![截圖 2025-11-20 凌晨2.06.46](https://hackmd.io/_uploads/BJgBDKjx-x.png) **ShiftRows 之 Pseudocode** ```python= ShiftRows(S) { for(r=1 to 3) shiftrow(s_r, r) # s_r 為第 r 列 } shiftrow(row, n) # n 為位移的位元組數 { CopyRow(row, t) # t 為暫時列 for(c=0 to 3) row_{(c-n) mod 4} <- t_c } ``` ![截圖 2025-12-09 晚上11.16.37](https://hackmd.io/_uploads/BkGvp3SMbg.png) ### 05-03. MixColumns (行混合) **功能**:這是一種「Byte 間的變換 (Inter-byte transformation)」,依據相鄰 Byte 的內容來改變自身的位元。 **擴散效果 (Diffusion)**:透過混合運算,提供**位元層級 (Bit level)** 的擴散效果。 **操作細節**: * 以**行 (Column)** 為單位進行操作,將狀態矩陣的每一行轉換為新的行。 * 運算本質是矩陣乘法:`New_Column = Constant_Matrix * Old_Column`。 * **可逆性**:`InvMixColumns` 與 `MixColumns` 互為逆運算。 ![截圖 2025-11-20 凌晨2.07.04](https://hackmd.io/_uploads/HJ7IPFigZg.png) ![截圖 2025-11-20 凌晨2.07.17](https://hackmd.io/_uploads/B11PPYilWl.png) :::success **重點筆記** * 假設輸入行向量為 $\begin{bmatrix} D4 \\ BF \\ 5D \\ 30 \end{bmatrix}$。 * 透過常數矩陣乘法 (在 $GF(2^8)$ 下運算):$02 \cdot D4 \oplus 03 \cdot BF \oplus 01 \cdot 5D \oplus 01 \cdot 30 = 04$ * 最終該位置的輸出的 Byte 為 `04`。 ![截圖 2025-12-09 晚上11.19.22](https://hackmd.io/_uploads/r1HZ03SfZx.png) ::: **MixColumns 之 Pseudocode** ```python= MixColumns(S) { for(c=0 to 3) mixcolumn(s_c) } mixcolumn(col) { CopyColumn(col, t) # t 為暫時行 col_0 <- (0x02) dot t_0 XOR (0x03 dot t_1) XOR t_2 XOR t3 col_1 <- t_0 XOR (0x02) dot t_1 XOR (0x03) DOT t_2 XOR t3 col_2 <- t_0 XOR t_1 XOR (0x02) dot t_2 XOR (0x03) dot t_3 col_3 <- (0x03 dot t_0) XOR t_1 XOR t_2 XOR (0x02) dot t_3 } ``` ![截圖 2025-12-09 晚上11.26.43](https://hackmd.io/_uploads/Sk16JarGWg.png) ### 05-04. AddRoundKey (加入回合鑰) **功能**:將金鑰混合至狀態矩陣中。 **操作細節**: * 一次處理一個行 (Column)。 * 將狀態矩陣 (State) 與回合金鑰 (Round Key) 進行矩陣加法 (在二進位運算中即為 **XOR**)。 **特性**:`AddRoundKey` 的逆運算就是它自己 (因為 $A \oplus K \oplus K = A$)。 ![截圖 2025-11-20 凌晨2.07.37](https://hackmd.io/_uploads/BkVOvtjx-x.png) **AddRoundKey 之 Pseudocode** ```python= AddRoundKey(S) { for(c=0 to 3) s_c <- s_c XOR w_{round + 4c} } ``` <br> ## 06. 金鑰擴充 (Key Expansion) ### 06-01. 擴充機制 (以 AES-128 為例) AES 的運算需要為每一個回合 (Round) 提供一組獨立的金鑰。 * **目標**:將原始的 **128-bit** (4 個 words) 金鑰,擴展成 **$N_r + 1$** 組回合金鑰。 1. 對於 AES-128 (10 回合),共需要 11 組金鑰,總計 44 個 words ($w_0$ 到 $w_{43}$)。 ![截圖 2025-11-20 凌晨2.10.54](https://hackmd.io/_uploads/Bk_VOFseZx.png) * **基本流程**: 1. 前 4 個 words ($w_0 \sim w_3$) 直接由原始金鑰填入。 2. 後續的 words ($w_i$) 依賴於前一個 word ($w_{i-1}$) 和前一組對應位置的 word ($w_{i-4}$)。 ![截圖 2025-11-20 凌晨2.11.00](https://hackmd.io/_uploads/ByC4uKslbe.png) ### 06-02. 核心變換函數 在產生每回合的第一個 word (即 $i$ 為 4 的倍數) 時,會經過特殊的 $g$ 函數處理,包含以下步驟: **RotWord (字組循環移位)**: - 將 Word 中的 4 個 bytes 進行循環左移。 - **例子**:輸入 $(a, b, c, d) \rightarrow$ 輸出 $(b, c, d, a)$。 **SubWord (S-Box 代換)**:對 Word 中的 4 個 bytes 分別進行 S-Box 查表替換 (與加密步驟中的 SubBytes 相同)。 **RCon (Round Constant, 回合常數)**: - 將結果與回合常數進行 XOR 運算。 - **定義**:$RCon_i = (RC_i, \text{'00'}, \text{'00'}, \text{'00'})$。 - **數值**:$RC_i$ 代表 $x^{i-1}$ 在 $GF(2^8)$ 中的值。 - **序列**: 1. Round 1: `01 00 00 00` 2. Round 2: `02 00 00 00` 3. Round 3: `04 00 00 00` (以此類推,直到 `1B`, `36`...)。 ![截圖 2025-11-20 凌晨2.11.15](https://hackmd.io/_uploads/SkpS_Ysx-e.png) ![截圖 2025-11-20 凌晨2.11.22](https://hackmd.io/_uploads/ryrUutjgbg.png) **Key Expansion in AES-128 之 Pseudocode** ```python= KeyExpansion([key_0 to key_15], [w_0 to w_43]) { for(i=0 to 3) w_i <- key_4i + key_4i+1 + key_4i+2 + key_4i+3 for(i=4 to 43) { if(i mod 4 != 0) w_i <- w_i-1 + w_i-4 else { t <- SubWord(RotWord(w_i-1)) XOR RConi/4 # t 為暫時字組 w_i <- t + w_i-4 } } } ``` :::success **重點筆記**:金鑰擴充運算追蹤 (Key Expansion Trace) 以下表格展示了 AES-128 的實際運算數值,假設 Alice 與 Bob 議定的金鑰為 `24 75 A2 B3 ...` 。 **運算解讀**: - 每一回合開始時,先計算 **$t$** 值 (左欄),這是上一回合最後一個字經過 Rot/Sub/RCon 後的結果。 - 例如 Round 1 的 $w_4$ (`8955B5CE`) 是由 $t$ (`AD20177D`) 與 $w_0$ (`2475A2B3`) 進行 XOR 運算而得 ($AD \oplus 24 = 89$)。 ![截圖 2025-12-09 晚上11.44.57](https://hackmd.io/_uploads/rkBZ4prMbl.png) ::: :::success **重點筆記**:金鑰雪崩效應 (Avalanche Effect in Keys) **實驗設定**:使用兩組原始金鑰 (Cipher Keys),它們之間**僅有 1 個 bit 的差異**。 * Key 1: `... B2 CC AA 34 ...` * Key 2: `... B2 CC AB 34 ...` (僅 `AA` 與 `AB` 的差異) **實驗結果**: * **Round 1**:回合金鑰已有 **2 bits** 不同。 * **Round 2**:差異擴大至 **17 bits**。 * **Round 10**:差異達到 **52 bits**。 **結論**:即使原始金鑰極為相似,經過擴充演算法後,產生的回合金鑰將會截然不同,攻擊者無法透過分析相似金鑰來推導結果。 ![截圖 2025-12-09 晚上11.47.09](https://hackmd.io/_uploads/S1qtETBG-e.png) ::: :::success **重點筆記**:無弱金鑰特性 (No Weak Keys) **背景**:DES 演算法中存在所謂的「弱金鑰 (Weak Keys)」,即特定金鑰會導致生成的子金鑰呈現規律性。 **AES 實驗**:假設使用一把**全為 0** 的金鑰 (`00 00 ... 00`)。 **觀察結果**: * **Pre-round**: 全為 `00000000`。 * **Round 1**: 全為 `62636363` (這是 0 經過 S-Box 運算後的結果)。 * **Round 2**: 仍有部分規律 (如第一字組與第三字組相同 `9B9898C9`)。 * **Round 3 之後**:規律完全消失,字組變得隨機且無序。 **結論**:AES 的非線性設計 (S-Box) 與 RCon 機制確保了即使是全 0 金鑰,也能在幾回合內迅速打破規律,因此 AES **不存在弱金鑰**。 ![截圖 2025-12-09 晚上11.47.57](https://hackmd.io/_uploads/SyihV6Hz-x.png) ::: :::success **重點筆記**:AES-192 與 AES-256 的擴充演算法差異 AES-192 與 AES-256 的金鑰長度更長,因此擴充演算法與 AES-128 (以 4 個 words 為一組) 略有不同。 **AES-192** (金鑰長度 192 bits = 6 words) * 一次生成 **6** 個 words ($w_0$ 到 $w_5$ 為原始金鑰)。 * **運算規則**: 1. 若 $i \pmod 6 \neq 0$:$w_i = w_{i-1} \oplus w_{i-6}$ 2. 若 $i \pmod 6 = 0$ (每組的第一個字):$w_i = t \oplus w_{i-6}$ (其中 $t$ 經過 RotWord, SubWord, RCon 處理)。 **AES-256** (金鑰長度 256 bits = 8 words) * 一次生成 **8** 個 words ($w_0$ 到 $w_7$ 為原始金鑰)。 * **運算規則**: 1. 若 $i \pmod 8 \neq 0$ 且 $i \pmod 4 \neq 0$:$w_i = w_{i-1} \oplus w_{i-8}$ 2. 若 $i \pmod 8 = 0$ (每組的第一個字):$w_i = t \oplus w_{i-8}$ 3. **特殊規則**:若 $i \pmod 4 = 0$ 但 $i \pmod 8 \neq 0$ (即每組的中間): $$w_i = \text{SubWord}(w_{i-1}) \oplus w_{i-8}$$ *(這增加了一次額外的 S-Box 代換,以增強長金鑰的非線性度)*。 ::: ### 06-03. 整體架構 * **加密 (Cipher)**:依序執行 Rounds。 1. **初始階段 (Pre-round)**:AddRoundKey 2. **主要回合 (Rounds 1 ~ 9)**:SubBytes $\rightarrow$ ShiftRows $\rightarrow$ MixColumns $\rightarrow$ AddRoundKey 3. **最終回合 (Round 10)**:SubBytes $\rightarrow$ ShiftRows $\rightarrow$ **AddRoundKey** (無 MixColumns) * **解密 (Inverse Cipher)**: 1. 解密並非單純將加密流程倒過來跑,而是使用**逆變換 (Inverse Transformations)**:**InvShiftRows** (向右移)、**InvSubBytes** (逆 S-Box 表)、**InvMixColumns** (逆矩陣乘法)、**AddRoundKey** (XOR 自身即為逆運算) 2. 直接使用加密步驟的逆函數:`InvSubBytes`、`InvShiftRows`、`InvMixColumns`。 3. 必須逆向執行 (從 Round 10 到 Round 1)。 4. **缺點**:加密與解密的結構看起來不對稱,硬體實作時無法共用太多電路。 ![截圖 2025-11-20 凌晨2.15.12](https://hackmd.io/_uploads/By94tKjeZl.png) - 替代設計 (Alternative Design)為了讓解密流程在結構上更像加密流程 (便於軟硬體實作),可以調整順序: 1. **交換律**:`InvShiftRows` 和 `InvSubBytes` 的順序可以互換 (互不影響)。 2. **調整金鑰**:透過修改解密時的金鑰擴充演算法,可以讓 `InvMixColumns` 的位置調整到與加密時的 `MixColumns` 對應。 ![截圖 2025-11-20 凌晨2.15.25](https://hackmd.io/_uploads/BJwHYFil-e.png) **整體完整的架構** ![截圖 2025-11-20 凌晨2.12.02](https://hackmd.io/_uploads/By2_dFsl-g.png) ```python= Cipher(InBlock[16], OutBlock[16], w[0, ..., 43]) { BlockToState(InBlcok, S) S <- AddRoundKey(S, w[0 ... 3]) for(round = 1 to 10) { S <- SubBytes(S) S <- ShiftRows(S) if(round != 10) S <- MixColumns(S) S <- AddRoundKey(S, w[4 x round, 4 x round +3]) } StateToBlcok(S, OutBlcok); } ``` ### 06-04. AES-192 與 AES-256 的差異 雖然邏輯相似,但因金鑰長度不同,處理方式微調: * **AES-192**:一次生成 **6** 個 words。 * **AES-256**:一次生成 **8** 個 words。 * **特殊設計**:在 AES-256 中,當 $i \mod 8 = 4$ 時 (即一組金鑰的中間),會額外執行一次 `SubWord`,這是為了在長金鑰中增加足夠的非線性度。 ## 07. 實例演示 (Examples) ### 07-01. 標準加密實例 (Example 7.7) 這裡展示了一個標準的 AES 加密過程,使用隨機選取的金鑰對明文區塊進行加密。 - **輸入數據**: 1. **Plaintext (明文)**: `00 04 12 14 12 04 12 00 0C 00 13 11 08 23 19 19` 2. **Cipher Key (金鑰)**: `24 75 A2 B3 34 75 56 88 31 E2 12 00 13 AA 54 87` - **輸出結果**:**Ciphertext (密文)**: `BC 02 8B D3 E0 E3 B1 95 55 0D 6D FB E6 F1 82 41` ![截圖 2025-12-09 晚上11.56.19](https://hackmd.io/_uploads/SJZhU6BfZl.png) :::success **重點筆記**: 即使明文中有許多重複的 byte (如 `00`, `12`, `04` 出現多次),對應的密文卻完全看不出規律,這顯示了 AES 良好的隱藏能力。 ::: ### 07-02. 狀態變換過程追蹤 為了理解 AES 內部是如何運作的,我們追蹤**第 7 回合 (Round 7)** 的完整狀態變換。 假設第 7 回合的輸入狀態 (Input State) 與該回合的回合金鑰 (Round Key) 已知,流程如下: 1. **Input State (輸入狀態)**: $$ \begin{bmatrix} 18 & 0A & B9 & B5 \\ 64 & 68 & 6A & FB \\ 5A & EF & D7 & 79 \\ 8E & B2 & 10 & D4 \end{bmatrix} $$ 2. **After SubBytes (代換後)**: * 透過 S-Box 進行非線性替換 (例如 `18` $\rightarrow$ `AD`)。 $$ \begin{bmatrix} AD & 67 & EE & D5 \\ 43 & 45 & 02 & 0F \\ BE & DF & 0E & B6 \\ 19 & 37 & CA & 48 \end{bmatrix} $$ 3. **After ShiftRows (位移後)**: * 進行列位移 (Row 0 不動, Row 1 左移 1, Row 2 左移 2, Row 3 左移 3)。 * 注意第二列 `43 45 02 0F` 變成了 `45 02 0F 43`。 $$ \begin{bmatrix} AD & 67 & EE & D5 \\ 45 & 02 & 0F & 43 \\ 0E & B6 & BE & DF \\ 48 & 19 & 37 & CA \end{bmatrix} $$ 4. **After MixColumns (混合後)**: * 進行矩陣乘法,數值大幅改變。 $$ \begin{bmatrix} C8 & 67 & 5F & 61 \\ 7D & BB & 1E & E3 \\ 2C & 39 & DF & 76 \\ 37 & 2F & F6 & 77 \end{bmatrix} $$ 5. **Output State (AddRoundKey 後)**: * 加入回合金鑰,產生該回合的最終輸出,並成為下一回合的輸入。 $$ \begin{bmatrix} 62 & 04 & C5 & F7 \\ 83 & 9F & 9C & 81 \\ 3E & B3 & B9 & 3B \\ B6 & 95 & AD & 74 \end{bmatrix} $$ ![截圖 2025-12-01 凌晨1.07.48](https://hackmd.io/_uploads/H1ylceqWWe.png) ### 07-03. 全零明文加密 (Example 7.9) 許多人好奇,如果明文非常簡單(例如全是 0),加密出來的結果會不會很單調? * **Plaintext**: `00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00` (全 0) * **Key**: (同 Example 7.7) * **Ciphertext**: `63 2C D4 5E 5D 56 ED B5 62 04 01 A0 AA 9C 2D 8D` > **結論**:即使輸入是最簡單的全 0 數據,經過 AES 的多次變換後,輸出的密文依然呈現高度隨機性,沒有明顯規律。 ### 07-04. 雪崩效應驗證 (Example 7.10 - Avalanche Effect) 此範例驗證了加密演算法的重要特性:**擴散 (Diffusion)** 與 **混淆 (Confusion)**。我們比較兩個僅有 **1 bit** 差異的明文,其加密結果差異有多大。 * **Plaintext 1**: `... 00 00` (最後一個 Byte 為 00) * **Plaintext 2**: `... 00 01` (最後一個 Byte 為 01,僅最後 1 bit 不同) **加密結果比較**: * **Ciphertext 1**: `63 2C D4 5E 5D 56 ED B5 62 04 01 A0 AA 9C 2D 8D` * **Ciphertext 2**: `26 F3 9B BC A1 9C 0F B7 C7 2E 7E 30 63 92 73 13` :::success **重點筆記**:輸入端僅改變 **1 bit**,輸出端的密文卻有 **超過一半的 bits** 發生了翻轉。兩組密文看起來毫無關聯,這就是所謂的**雪崩效應**。 ::: ### 07-05. 全零金鑰加密 測試 AES 是否存在類似 DES 的弱金鑰問題。 * **Plaintext**: (同 Example 7.7) * **Key**: `00 00 00 00 ... 00` (全 0 金鑰) * **Ciphertext**: `5A 6F 4B 67 57 B7 A5 D2 C4 30 91 ED 64 9A 42 72` ### 07-06. 結論 即便使用全 0 的金鑰,由於 AES 的金鑰擴充演算法 (Key Expansion) 引入了 RCon 和 S-Box,後續的回合金鑰會變得非常複雜,因此**產生的密文依然安全且隨機**。這證實了 AES 對於簡單金鑰模式具有強大的抵抗力。 <br> <br> ## 08. AES 的安全性分析 (Security Analysis) AES 當初設計的目的就是為了取代 DES,因此它經過了嚴格的測試,針對所有已知對 DES 有效的攻擊手法都進行了驗證。截至目前,尚未發現能有效攻破 AES 的方法。 ### 08-01. 架構上的安全機制 AES 的安全性來自於其變換步驟的數學特性: * **非線性變換 (Nonlinearity)**: 1. **來源**:**SubBytes** (S-Box)。 2. **作用**:這是 AES 安全性的核心。如果密碼系統全是線性的,攻擊者可以輕易透過線性代數解出金鑰。S-Box 阻斷了這種可能性。 * **擴散效果 (Diffusion)**: 1. **來源**:**ShiftRows** 與 **MixColumns**。 2. **作用**:確保輸入的每一個 byte 都能影響輸出的多個 bytes (雪崩效應),讓統計分析變得極其困難。 * **無弱金鑰 (No Weak Keys)**: 1. **來源**:**Key Expansion** (金鑰擴充演算法)。 2. **作用**:AES 不像 DES 或其它舊演算法有特定的「弱金鑰」。即使兩個金鑰只差 1 bit,擴充出來的整組回合金鑰也會完全不同。 ### 08-02. 抵抗攻擊的能力 **暴力破解 (Brute-Force Attack)**: - AES 最短的金鑰為 128 bits。 - 嘗試次數需達 $2^{128}$ 次。相比 DES 的 56 bits,這是一個天文數字的差距,以現有算力幾乎不可能窮舉。 **統計攻擊 (Statistical Attack)**: - 由於高強度的混淆 (Confusion) 與擴散 (Diffusion),經過測試證實 AES 能有效抵抗統計分析。 **差分與線性攻擊 (Differential and Linear Attacks)**: - AES 的設計者在開發階段就已將這些攻擊納入考量,並優化了 S-Box 與矩陣運算來免疫這些攻擊。 ## 08-03. 實作特性與成本 (Implementation & Cost) **高度的實作彈性**:AES 的設計非常靈活,適用於各種環境 * **平台**:可實作於軟體 (Software)、硬體 (Hardware) 或韌體 (Firmware)。 * **實作方法**: 1. **查表法 (Table Lookup)**:犧牲空間換取時間,適合記憶體夠用的系統,速度極快。 2. **代數運算法**:直接進行 $GF(2^8)$ 運算,適合記憶體受限的環境 (如晶片卡)。 **簡單與低成本**:演算法邏輯簡潔,不需要昂貴的高效能處理器 * 記憶體需求低 (Minimum amount of memory),使其非常適合應用在**智慧卡 (Smart Cards)**、**IoT 裝置**等低成本硬體上。 <br> ## 09. AES 與 3DES 的終極比較 3DES (Triple DES) 是在 DES 被破解後的過渡方案,雖然安全性提升,但效率低落。AES 則在各方面都全面勝出。 ### 09-01. 規格比較表 <center> | 特性 | 3DES (Triple DES) | AES | | :--- | :--- | :--- | | **明文區塊 (Block Size)** | 64 bits (較小,易受特定攻擊) | **128 bits** (標準且安全) | | **金鑰長度 (Key Length)** | 112 bits ($56 \times 2$) 或 168 bits ($56 \times 3$) | **128, 192, 256 bits** | | **運算回合數** | 48 回合 (運算繁重) | **10, 12, 14 回合** (效率高) | | **加密速度** | 慢 (Slow) | **快 (Fast)** | </center> ### 09-02. 效能實測數據 (Benchmark) 測試環境假設:256 MB 資料量,Pentium 4 2.1 GHz CPU (舊世代硬體基準) <center> | 測試項目 | 3DES | AES | 結論 | | :--- | :--- | :--- | :--- | | **加密時間** | 12 秒 | **5 秒** | AES 速度快 **2.4 倍** | | **平均吞吐量** | 12 MB/s | **51.2 MB/s** | AES 處理效率極高 | | **暴力破解所需時間** | 46 億年 | **149 兆年** | AES 安全性是指數級的提升 | </center> ### 09-03. 總結 AES 不僅在安全性上遠超 3DES (149 兆年 vs 46 億年),在運算效率上也大幅領先,這也是為何現今 Wi-Fi、HTTPS、VPN 都全面採用 AES 的原因。