Hash

32 個字節對於雜湊是否足夠,還有什麼是“過度工程”嗎?

  • July 6, 2022

為了數據完整性,特別是對於小數據塊,而不是使用 SHA-256 雜湊,或者簡單地截斷 SHA-512 雜湊,我正在使用以下想法:

function saferHash(data) {
   let hash1Entropy = 42;  // sha512:42
   let hash2Entropy = 4; // 4B extra possible protected outcomes in case of highly unlikely collision in hash 1
   const hash1  = sha512(data).slice(0,hash1Entropy); // for 42 byte entropy, truncated to save space + prevent length extension vulnerabilities 
   const hash2 = blake3(data).slice(0,hash2Entropy); // cheapest extra forgery prevention in case of sha512:42 hash collision, truncated to save space + prevent length extension vulnerabilities 
   return new Uint8Array([...hash1,...hash2]); // 46 byte total hash  
}

這是否完全過度設計了整個事情,或者將熵增加到 +32 字節並使用額外的廉價散列函式 (blake3) 來進一步增加創建碰撞的難度實際上是不是太糟糕了?

  1. 是的,32 字節/256 位就足夠了(請認真閱讀這篇博文)。該長度提供 $ 2^{128} $ 抗碰撞性和 $ 2^{256} $ SHA256的原像第二原像電阻等等。
  2. 48 字節/384 位或 64 字節/512 位提供了更高的安全性,在某些情況下使用起來更合理,但在其他情況下則不必要。例如,如果您要對Ed25519的消息進行預散列,則需要使用 512 位散列來最大化抗碰撞性。
  3. 這是過度工程。您所做的比使用正常 SHA512 弱,因為抗碰撞性取決於輸出的長度。4 字節的輸出太小,不應該使用。BLAKE3 的預設輸出長度為 32 字節/256 位,通常不應低於任何無鍵散列函式的長度。42 字節也是一個奇怪的選擇。無需使用多個雜湊函式或重新發明輪子。如果單個散列對於完善的現實世界協議來說足夠好,那麼它對您來說就足夠了。
  4. 為了防止長度擴展攻擊,要麼使用 SHA512/256,要麼使用更現代的散列函式,例如 BLAKE2、SHA3 或 BLAKE3(我認為按此順序)。你不需要截斷 BLAKE3 來避免長度擴展攻擊。

通過截斷散列,實際上增加了每個散列的衝突率。

最終對於一定數量的字節,並且考慮到算法是靜態的並且相對安全(通過具有接近一致的輸出),衝突率將或多或少保持不變。

您唯一要阻止的可能是彩虹表,如果某個雜湊表存在,對於您的特定組合,大多數都不會存在。

總而言之,我認為這是過度設計,並且完全使用 sha-512 比截斷每個並重新發明輪子更安全、更方便且絕對更快。

簡而言之,您正在截斷更慢且“更好”的算法,減少您從中獲得的“好”熵,並用“更便宜”的算法替換它。

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