回想第 6 章:許多雜湊函式的壓縮函式都建立在區塊密碼上。
例如 HMAC-SHA-256 這個 PRF,是一連串對 SHA-256 壓縮函式的呼叫,而該壓縮函式本身又是一個重複輪序列的區塊密碼。
換句話說:HMAC-SHA-256 是「HMAC 建構裡的雜湊裡的壓縮函式裡的區塊密碼」。
那為什麼不直接使用區塊密碼,而要疊這麼多層?
CMAC(cipher-based MAC)正是這樣的建構:它只用一個區塊密碼(例如 AES)就創造出一個 MAC。
CMAC 雖不如 HMAC 流行,但被部署在許多系統中,包括 IPSec 套組的一部分——網際網路金鑰交換(IKE)協定。例如 IKE 用一個稱為 AES-CMAC-PRF-128 的建構(以 AES 為基礎、128 位元輸出的 CMAC)作為核心演算法來產生金鑰材料。
CMAC 規範於 RFC 4493。
先看它的前身:CBC-MAC#
CMAC 於 2005 年設計,是 CBC-MAC 的改良版——後者是一個從 CBC 區塊密碼運作模式衍生、更簡單的區塊密碼式 MAC。
CBC-MAC 很簡單:給定區塊密碼 E,要計算訊息 M 的標籤,你就用全零初始值(IV) 以 CBC 模式加密 M,然後丟棄除最後一個密文區塊以外的一切:
C₁ = E(K, M₁)
C₂ = E(K, M₂ ⊕ C₁)
C₃ = E(K, M₃ ⊕ C₂)
...只保留最後的 Cᵢ,那就是 M 的 CBC-MAC 標籤。簡單——也簡單到容易被攻擊。
為什麼 CBC-MAC 不安全#
考慮單區塊訊息 M₁ 的 CBC-MAC 標籤 T₁ = E(K, M₁),以及另一則單區塊訊息 M₂ 的標籤 T₂ = E(K, M₂)。
給定
(M₁, T₁)與(M₂, T₂)這兩對,你可以推導出:T₂同時也是雙區塊訊息M₁ ‖ (M₂ ⊕ T₁)的標籤。驗證一下——對
M₁ ‖ (M₂ ⊕ T₁)套用 CBC-MAC:C₁ = E(K, M₁) = T₁ C₂ = E(K, (M₂ ⊕ T₁) ⊕ T₁) = E(K, M₂) = T₂你在不知道金鑰的情況下,從兩對「訊息/標籤」造出了第三對。也就是說,你能偽造 CBC-MAC 標籤,攻破了它的安全性。
CMAC 如何修正#
CMAC 修正 CBC-MAC 的做法是:用與前面各區塊不同的金鑰處理最後一個區塊。
衍生兩把子金鑰#
CMAC 先從主金鑰 K 衍生出兩把金鑰 K₁ 與 K₂,使 K、K₁、K₂ 三者相異:
- 計算一個暫時值
L = E(0, K)——這裡0扮演區塊密碼的金鑰,K扮演明文區塊。 - 若
L的最高位元(MSB)是 0,令K₁ = (L << 1);若 MSB 是 1,令K₁ = (L << 1) ⊕ 87。 - 若
K₁的 MSB 是 0,令K₂ = (K₁ << 1);否則K₂ = (K₁ << 1) ⊕ 87。
數字 87 是為了資料區塊為 128 位元時的數學性質而審慎挑選的;區塊不是 128 位元時需要另一個值。
最後一個區塊的兩種情況#
有了 K₁ 與 K₂,CMAC 的運作就與 CBC-MAC 相同,除了最後一個區塊:
最後區塊 Mn 的狀況 | 標籤 |
|---|---|
| 恰好是一個區塊的大小 | E(K, Mn ⊕ C(n−1) ⊕ K₁) |
| 比一個區塊短 | 先補一個 1 位元與若干 0,再算 E(K, Mn ⊕ C(n−1) ⊕ K₂) |

圖 7-3:CMAC 建構:訊息恰為整數個區塊時

圖 7-4:CMAC 建構:最後一個區塊必須以 1 位元與若干 0 填充時
注意第一種情況只用
K₁、第二種只用K₂,但兩者處理最後一個區塊之前的訊息片段時都只用主金鑰K。
CMAC 是確定性的#
與 CBC 加密模式不同,CMAC 不接收 IV 參數,是確定性的:對給定訊息
M,CMAC 永遠回傳相同的標籤,因為CMAC(M)的計算沒有被隨機化。而這樣沒問題——因為與加密不同,MAC 的計算不需要隨機化就能安全,這也免除了必須挑選隨機 IV 的負擔。