組合兩個安全分組密碼會不安全嗎?
假設我們有兩個安全分組密碼 FOO 和 BAR。通過將它們組合成一個新的分組密碼而建構的新分組密碼會導致任何不安全性嗎?
$$ \begin{align} \operatorname{BAZ}_K(x)&=\operatorname{FOO}_K(\operatorname{BAR}_K(x))\ \operatorname{BAZ}^{-1}_K(x)&=\operatorname{BAR}^{-1}_K(\operatorname{FOO}^{-1}_K(x)) \end{align} $$
這取決於您所說的“安全分組密碼”是什麼意思,但是在足夠強大的定義(被認為在實踐中成立)下,由於無聊的原因,答案是否定的。如果我們有一些分組密碼 $ F_k $ 這樣 $ F_{k}^{-1} $ 也是一個安全的分組密碼,然後組成:
$$ (F_k\circ F_k^{-1})(x) = x $$ 不會是安全的分組密碼。
因此,如果我們想證明這個(人為的)反例是正確的,我們需要 $ F_k $ 作為一個安全的分組密碼來暗示 $ F_k^{-1} $ 也是。這不適用於分組密碼安全性的“標準”概念(將 PRP 與隨機區分開來),但如果您還允許對手查詢“逆”函式,則確實如此。
實踐中的大多數分組密碼被認為滿足這個更強的定義,但是這種不安全的結構(組合一個分組密碼及其逆)是對您的想法的“愚蠢”攻擊,並且依賴於兩個分組密碼( $ F_k $ 和 $ F_k^{-1} $ ) 在數學上共享大量結構。
答案是:理論上,也許……但在實踐中,一百萬年(字面意思)永遠不會。
如果密碼太相似(
BAR
幾乎與的解密功能相同FOO
),假設您在兩者中使用完全相同的密鑰,它們可能會相互抵消。但在實踐中,只要每個單獨的密碼都是安全的,您可能仍然會獲得更安全的密碼 - 並且可能即使它們不安全。為什麼?
讓我們看一下 SP-Networks(大多數現代密碼的基礎)……你使用一個圓形函式,一些非線性可逆函式來模糊每個(通常是字節)的含義。然後,您將這些位與消息中某個完全不同字節的位混合在一起。這樣做,單個位的差異意味著改變整個消息。因此,即使是一個幾乎完美的解密函式也只會增加更多的非線性。如果任何一種算法都有一個區別,那麼你能做的最糟糕的事情就是讓它不再比原來更安全。
但是,如果您使用 2 種不同的加密算法,則可以將它們視為 2 種算法的 1 種“產品密碼”。假設您使用 AES-256 和 Serpent-256 ……您可以對兩者使用相同的密鑰並有效地從
Serpent(AES(message))
. 前 14 輪是 AES 輪,後 32 輪是 Serpent 輪,結果是一個具有 AES 和 Serpent 組合密碼強度的密碼。如果您可以單獨破解每個密碼,則不會出現這種情況,但是由於
AES(message)
除了作為 Serpent 的消息之外,您從不使用任何地方,因此 AES 密文成為您的超級密碼的內部狀態。因此,單獨破壞任何一種算法都無濟於事,即使同時破壞兩者也不一定能讓你做任何有用的事情。您不僅需要破解兩個密碼,還需要破解它們之間的關聯。話雖如此,作為標準做法,您應該為每種算法使用不同的密鑰。這並不是數學上真正需要的,但如果你不這樣做,你會被取笑……以及將自己暴露在一個不切實際的小風險中,在任何理性的頭腦中都無關緊要,但如果你這樣做可能會毀了你’真的很倒霉。
更新:如果您擔心其中一種算法具有側通道攻擊,您應該首先使用沒有可能的側通道攻擊的算法。這樣,任何側通道都可以簡單地恢復密文。這種策略只有在密鑰都是相互獨立的情況下才有效(也就是知道一個密鑰不能說明另一個密鑰)。
更新 2:
在現實世界中,您最終的安全性會降低嗎? 假設我們使用了 2 種算法:
AES
假設SEA
… SEA 與 AES 相同,除了 SEA 解密輪是 AES 加密輪。假設 SEA 的最後 5 個輪密鑰與前 5 個 AES 輪密鑰相同,但其他輪密鑰不同。我們還假設 SEA 總共使用 7 輪。我們得到:
// [algo]_ENC = a single encryption round // [algo]_DEC = a single decryption round msg = AES_ENC(msg) msg = AES_ENC(msg) msg = AES_ENC(msg) msg = AES_ENC(msg) msg = AES_ENC(msg) msg = AES_ENC(msg) msg = AES_ENC(msg) msg = AES_ENC(msg) msg = AES_ENC(msg) msg = AES_ENC(msg) msg = AES_ENC(msg) msg = AES_ENC(msg) msg = AES_ENC(msg) msg = AES_ENC(msg) msg = AES_DEC(msg) msg = AES_DEC(msg) msg = AES_DEC(msg) msg = AES_DEC(msg) msg = AES_DEC(msg) msg = SEA_ENC(msg) msg = SEA_ENC(msg)
注意一些
AES_ENC
s 是如何被 取消的AES_DEC
?由於這些輪次的 AES_DEC 是 SEA_ENC,我們有效地將我們的密碼簡化為修改後的 9 輪 AES。由於我們假設的 SEA 只有 7 輪,我們最終比普通 AES 少了 3 輪。*除非您的算法 BAR 是專門為撤消 FOO 而設計的,否則您可能沒問題。
在現實生活中,使用的任何兩種算法都不會產生這種結果(除非您特別試圖降低它的安全性)。我只是包括那個例子來解釋它是如何發生的。
還有其他方法可以以較低的安全性結束,但它們都需要
BAR
是FOO
. 從理論上講,您可以找到 aBAR
不是 foo 的倒數,但設法降低安全性,但這是純粹的理論攻擊。找到這樣的難度BAR
與破壞您的原始算法大致相同。