Block-Cipher

如何用部分已知的明文破解 CBC 密碼?

  • March 3, 2020

我正在學習一些 IT 安全性,在實踐中我發現了一個我無法解決的練習。

我有一條在 CBC 模式下使用分組密碼的加密消息。這些塊是一個字節長,第一個塊是 IV。我知道 80% 的明文是一種形式,但缺少部分。我對加密功能一無所知。

我應該使用哪種攻擊方法,從哪裡開始?

我知道 $ C_1=Enc_k (M_1\oplus C_0) $ . 我知道 $ C_1 $ , $ M_1 $ 和 $ C_0 $ ,四。

$ \mathrm{Enc}_k $ 總是將相同的塊值轉換為相同的塊值。由於塊只有一個字節長,因此只有 256 個不同的塊值。所以你可以從你知道的明文部分建構一個表格。一旦你建立了那個表,你可以在相反的方向使用它來計算 $ \mathrm{Dec}_k $ .

$$ \begin{array}{l|l} x & \mathrm{Enc}_k(x) \ \hline 0 & _ \ 1 & _ \ \vdots \ 255 & _ \ \end{array} $$

會心 $ M_1 $ , 方程 $ C_1 = \mathrm{Enc}k(M_1 \oplus C_0) $ 為您提供表中的一項。更一般地說,只要你知道價值 $ M_i $ , 方程 $ C{i+1} = \mathrm{Enc}k(M{i+1} \oplus C_i) $ 為您提供表中的一項。一些職位可能會呼叫 $ \mathrm{Enc}_k $ 在與另一個位置相同的輸入上,因此在明文中可能需要超過 256 個已知字節,但是對於幾百個字節的已知明文,失去條目的機率會迅速降低¹,因為不同值的輸入 $ i $ 本質上是隨機的。

如果表中存在缺失值,您可以通過兩種方式縮小範圍。首先,由於 $ \mathrm{Enc}_k $ 是一個排列,第二列中的所有值都是不同的。二、所有 $ M_i $ 可能是可列印的字元,這限制了可能性。在練習的範圍內,我希望如果有任何空白,它們很容易通過一點手動計算來填補。

問題的核心是 8 位塊。一個 8 位塊太短了。在現實世界中,DES 和 ((X)X)TEA 等較舊的分組密碼具有 64 位分組,而現代分組密碼具有 128 位分組。即使使用 64 位塊,這樣的表攻擊也不太可能產生任何有用的結果(該表需要 128 EiB 的儲存空間,並且您需要大致相同數量的具有已知密文的可猜測明文來建構它)。64 位塊容易受到這種攻擊的稀疏版本的攻擊,您希望在這種攻擊中 $ \mathrm{Enc}k $ 已在同一輸入上被呼叫兩次,這揭示了有關消息的某些內容(如果 $ C_i = C_j $ 然後 $ M_i \oplus C{i-1} = M_j \oplus C_{j-1} $ ,這揭示了價值 $ M_i \oplus M_j $ ,特別是揭示 $ M_j $ 如果你知道的話 $ M_i $ )。你只需要大約 $ 2^{32} $ 消息塊有相當大的機會重複塊值(生日綁定),這使得這種攻擊實用(最著名的是Sweet32)。

CBC 本身俱有具有適當大小的塊和隨機 IV 的塊密碼,即使針對選擇明文攻擊 ( IND-CPA )也是安全的。但是,對於自適應選擇明文攻擊,它根本不安全,攻擊者可以在看到密文的前一部分後送出一些明文進行加密。

在自適應情況下,我知道 $ C_i $ 並允許送出 $ M_{i+1} $ 這讓我學習 $ C_{i+1} = \mathrm{Enc}k(M{i+1} \oplus C_i) $ . 所以我選擇 $ M_{i+1} = C_i \oplus x $ 這樣我就可以學習 $ \mathrm{Enc}k(x) $ 對於任意 $ x $ . 如果我猜到了一個合理的值 $ M_j $ 對於一些 $ j $ ,這讓我可以通過測試是否 $ C{i+1} = C_j $ .

實踐中使用的CBC通常並不安全,因為它需要填充,因為 CBC 只能加密整數個塊。在攻擊者可以送出選擇的密文的情況下, Padding 很容易受到padding oracle 攻擊。這就是不推薦使用 CBC 的原因,尤其是在通信方面。(可以儲存對手可能能夠看到密文的儲存,例如從洩露的備份中,但無法注入密文。)

¹除非 $ \mathrm{Enc}_k $ 有一定的相關性 $ M $ .

引用自:https://crypto.stackexchange.com/questions/77975