回想第 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₂,使 KK₁K₂ 三者相異:

  1. 計算一個暫時值 L = E(0, K)——這裡 0 扮演區塊密碼的金鑰,K 扮演明文區塊。
  2. L 的最高位元(MSB)是 0,令 K₁ = (L << 1);若 MSB 是 1,令 K₁ = (L << 1) ⊕ 87
  3. 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 的負擔。