並行計算大文件的雜湊碼是否比順序計算更不安全?
我想提高散列大文件的性能,例如幾十 GB 的大小。
通常,您使用散列函式(例如 SHA-256,儘管我很可能使用 Skein,但與從
$$ fast $$固態硬碟)。我們稱之為方法 1。 這個想法是在 8 個 CPU 上並行散列文件的多個 1 MB 塊,然後將連接的散列散列成單個最終散列。我們稱之為方法 2,如下所示:
我想知道這個想法是否合理以及損失了多少“安全性”(就更可能發生的衝突而言)與在整個文件的跨度上進行單個散列。
例如:
讓我們使用 SHA-2 的 SHA-256 變體並將文件大小設置為 2^35=34,359,738,368 字節。因此,使用簡單的單通道(方法 1),我將獲得整個文件的 256 位散列。
將此與以下內容進行比較:
使用並行散列(即方法 2),我會將文件分成 32,768 個 1 MB 的塊,使用 SHA-256 將這些塊散列為 32,768 個 256 位(32 字節)的散列,連接散列並進行最終散列結果連接了 1,048,576 字節的數據集,以獲得整個文件的最終 256 位雜湊。
就碰撞的可能性和/或可能性而言,方法 2 是否比方法 1 更不安全?也許我應該將這個問題改寫為:方法 2 是否使攻擊者更容易創建一個散列到與原始文件相同的散列值的文件,當然除了一個微不足道的事實,即蠻力攻擊會更便宜,因為雜湊可以在N個cpus上並行計算嗎?
更新:我剛剛發現我在方法 2 中的構造與hash list的概念非常相似。但是,與方法 1(文件的普通舊雜湊)相比,上句中的連結引用的 Wikipedia 文章沒有詳細說明雜湊列表在衝突機會方面的優劣,當只有頂部雜湊時使用雜湊列表。
如果您仍然想使用 Skein(SHA-3 候選者之一):它具有用於樹散列的“操作模式”(配置變體),就像您的方法 2 一樣工作。
它在操作內部執行此操作,就像在各個塊上多次呼叫*UBI 。*這在Skein 規範文件(版本 1.3)的第 3.5.6 節中進行了描述。
您將需要 1 MB 的葉大小(因此,對於 512 位變體,Y_l = 14,對於 256 是 15,對於 1024 是 13)和您的應用程序的最大樹高度 Y_m = 2。(該圖顯示了一個 Y_m >= 3 的範例。)
這篇論文並沒有真正包括對樹散列模式的任何密碼分析,但它被包括在內(甚至被提到作為密碼散列的可能用途)似乎意味著作者認為它至少與“標準" 順序模式。*(證明文件*中也根本沒有提到。)
在更理論的層面上:
在雜湊函式中查找衝突的大多數方法都依賴於在底層壓縮函式 f : S × M -> S 中查找衝突(它將先前狀態與數據塊一起映射到新狀態)。
這裡的碰撞是其中之一:
- 一對消息和一個狀態,使得 f(s, m1) = f(s, m2)
- 一對兩個狀態,一個消息塊,使得 f(s1, m) = f(s2, m)
- 一對消息和一對狀態,使得 f(s1, m1) = f(s2, m2)。
第一個是最容易利用的——只需修改一個消息塊,讓所有其他塊相同。
要使用其他的,我們還需要對先前塊的壓縮函式進行原像攻擊,這通常被認為更加複雜。
如果我們有第一種類型的衝突,我們可以在樹版本和順序版本中利用它,即在最低級別。為了在較高級別上創建碰撞,我們再次需要在較低級別上進行原像攻擊。
因此,只要散列函式(及其壓縮函式)具有抗原像性,樹版本的碰撞弱點不會比“長流”版本多。