為什麼使用錯誤 IV 的 CBC 解密仍然給出可讀的結果?
在開發一些使用 .NET AesManaged 算法的程式碼時,我犯了一些錯誤,但對結果感到驚訝。
我的加密是正確的。我正在生成一個隨機 IV 塊並將其寫入文件(不加密 IV)。然後我正在加密明文並編寫它。
雖然解密是錯誤的……而不是從文件中讀取第一個塊並將其用作IV,它只是使用隨機IV並解密所有內容。第一個塊出現亂碼,但第二個(和後續)塊被正確解密!為什麼會這樣?
甚至更奇怪…當我嘗試通過在加密程式碼中加密 IV 來修復它(而不是不更改地寫入 IV)時,解密結果是一樣的!(亂碼然後正確解密塊)。
雖然我最終修復了我的程式碼,但這些結果有什麼意義呢?
在正確使用 CBC 模式時,您應該看到以下內容:
$ c_1=E_k(IV\oplus p_1), c_2=E_k(c_1\oplus p_2) $ 等
,解密為:
$ p_1=D_k(c_1)\oplus IV, p_2=D_k(c_2)\oplus c_1 $ , ETC
從您所說的來看,聽起來您已儲存在文件中(對於案例1):
$ IV||c_1||c_2||\cdots $ (在哪裡 $ || $ 是串聯)。
那麼,解密會做什麼呢?它會讀 $ IV $ 並嘗試解密它(聽起來程式碼認為讀取的第一個塊是密文的第一個塊)。由於它沒有要使用的 IV,它可能會使用發生在該記憶體位置的任何內容(因為它是一個未初始化的變數)。所以它確實 $ D_k(IV)\oplus R $ (在哪裡 $ R $ 是恰好位於該記憶體位置的隨機值)。這是你看到的隨機亂碼塊。然後,它讀取 $ c_1 $ 和用途 $ IV $ 作為前一個密碼塊並正確計算 $ p_1=D_k(c_1)\oplus IV $ .
對於第二種情況,根據您的描述,您不清楚您是如何加密的 $ IV $ . 你用什麼IV來加密IV?撇開這一點不談,在這種情況下也發生了非常相似的事情。我會讓你弄清楚細節。