在 CBC 實現中禁用填充完整性檢查是克服/減輕填充 oracle 攻擊的好方法嗎?
鑑於 CBC 模式具有填充預言攻擊,禁用填充完整性檢查是克服漏洞的好方法(這可能會導致現有使用者在解決初始向量不匹配方面感到沮喪,但這至少不會呈現模式本身很脆弱)?
TL,DR:不。使用適當的認證加密,例如在 GCM 或 CCM 模式下使用分組密碼。
預言機攻擊密碼的原理是對手有一個他們想要解密的密文。攻擊者對密文進行一些修改,對相應的明文做出合理假設,安排對修改後的密文進行解密,並查明假設是否正確。然後對手再次嘗試不同的假設。
一個合理假設的例子是“也許最後一個字節就是這個值”。這是合理的,因為隨機明文有 1/256 的機會匹配它,因此只需不到 256 次嘗試即可找出最後一個字節的值。一個不可信假設的例子是“也許最後一個塊正是這個特定的字元串”:它需要 $ 2^{256}-1 $ 通過重複這種形式的嘗試來嘗試查找塊的內容。
填充預言攻擊是一種預言攻擊,其中資訊來自填充知識。系統可能會洩漏此資訊,因為它返回“無效填充”錯誤,或者因為它以不同的方式處理有效和無效填充,因此兩者之間存在時間差異。無論明文如何,填充預言都可能起作用,儘管像幸運十三這樣的人利用了關於明文的部分知識。
填充有效性可能是預言機的一個方便組件,但它不是唯一的。處理解密數據的應用程序可能會對允許建構預言機的特製明文有自己的反應。舉一個簡單的例子,考慮兩個系統:
- 系統 1 使用 CBC 加密任意長度的消息,並帶有 PKCS#7 填充。
- 系統 2 使用 CBC 加密長度為 16 倍數的消息。生成消息的應用程序從任意長度的消息開始,並對其應用 PKCS#7 填充。
這些系統完全相同,但係統 2 不涉及加密子系統中的填充。所以你可以說系統 1 上的填充預言攻擊是系統 2 上的應用程序數據預言——移動填充並沒有改變任何東西。
再舉一個不那麼瑣碎的例子,POODLE是針對 SSL 3.0 的填充預言機。即使不檢查填充的系統也很容易受到攻擊,因為消息的確切長度取決於加密的內容,並且確定長度本身就是一個預言。(可以說它可以被認為是一個部分填充的預言機。)
預言機攻擊包含三個組成部分,移除這三個部分中的任何一個都會使攻擊失敗。
- 對手必須能夠注入特製的密文。
- 系統對不同密文的響應必然有一些可觀察到的差異,例如是否返回錯誤資訊、是否執行一些後續動作、處理的時機等。
- 攻擊者必須能夠構造具有關於相應明文的合理假設的密文。通常,攻擊是迭代的:對手一次只學習一點資訊,並使用每次嘗試來完善他們對系統的了解。
第一個屬性是安全模型的一部分。對手要麼是主動的,要麼是被動的。Oracle 攻擊需要一個活躍的對手。攻擊者完全被動的系統範例是通過物理安全介質進行的通信,其中攻擊者可以通過諸如電磁輻射之類的側通道觀察數據,但不能發送自己的數據。另一個例子是儲存,唯一的威脅是儲存介質被盜,系統永遠不會處理受污染的密文。如果您的威脅模型只有被動對手,您無需擔心預言機攻擊,您可以使用 CBC。
第二個屬性取決於應用程序,但它實際上是不可能的。除非您的應用程序只是丟棄它收到的消息,否則它肯定會對它們做一些事情。一旦它做了一些外部可見的事情,你就輸了。所以那裡沒有希望。
第三個屬性取決於密碼的構造、數據格式以及應用程序如何處理數據。預言機的存在並不是給定的——但很難確定不存在預言機。例如,幸運 13花了數年時間才被發現,它依賴於 13 個字節長(因此得名)的 TLS 消息頭比加密塊短一點的事實,但它是毀滅性的針對 TLS 中有效實現的 CBC 的攻擊。如果填充不是問題,則數據處理的其他方面可能是問題。
使第三個屬性無效的可靠方法是通過驗證明文來使其無法對明文做出合理的假設。如果系統收到消息後首先要做的是檢查其真實性,那麼系統的響應要麼是“此消息是真實的(可能還有更多資訊)”或“此消息是偽造的”。只要攻擊者不能破壞身份驗證,系統的響應將(極有可能)是“此消息是偽造的”,除非該消息是攻擊者從有效發件人處截獲的消息。因此,對手將無法學到任何東西。
因此,如果您的威脅模型包含活躍的攻擊者,您需要對您的消息進行身份驗證。您可以通過獲取密文的MAC並將其發送來做到這一點。這是一種“先加密後 MAC”結構,它避免了填充預言機攻擊。相比之下,POODLE 和幸運十三攻擊是可能的,因為 SSL/TLS 使用“MAC-then-encrypt”結構並且 MAC 保護應用程序數據(因此不能對應用程序行為進行預言攻擊)但不保護填充(允許預言機看起來像填充)。我們應該先 MAC-then-encrypt 還是先加密-then-MAC?討論了這兩種方法的相對好處,並指出兩者都有缺陷。
為避免這些陷阱,請不要自行組合加密和身份驗證。使用標準的經過身份驗證的加密算法。讓算法設計者操心如何設置密鑰,以什麼順序做事等。