Hash

密碼雜湊鹽

  • February 7, 2020

我問這個問題是為了對此有專業意見,並檢查我的假設是否正確。這個問題源於我在 SO 上交換的一些評論:登錄問題我可以使用任何使用者名和密碼登錄

採用這三種不同的方法來“保護”數據庫中的密碼(虛擬碼):

一:

global_salt = 'a salt string shared by your system and persistent in time'
hashed_password = hash( global_salt + password )
save(username, hashed_password)

二:

salt = generate_random_salt()
hashed_password = hash( salt + password )
save(username, salt, hashed_password)

三:

global_salt = 'a salt string shared by your system and persistent in time'
hashed_password = hash( global_salt + username + password )
save(username, hashed_password)

現在很明顯,salt首先使用 a 是明智的,可以藉助雜湊查找表來防止弱密碼重建。

但是讓我們假設我們選擇了一個global_salt從未改變過的隨機數和一個相當強大的散列函式。現在攻擊者已經獲得了對我們使用者表的訪問權限。我的假設是:

  • 對於試圖獲取特定使用者密碼的攻擊者來說,與其他技術相比,上述技術都不會帶來顯著的優勢;所有密碼都通過相同的算法和隨機鹽進行散列。
  • 在這種情況下,攻擊者將嘗試獲取所有使用者的密碼,第一種技術將給他帶來所有密碼共享相同鹽的優勢,從而降低整個任務的計算複雜性。但從我的角度來看,即使在這種情況下,第二種和第三種技術也沒有實質性的區別。

那麼,儘管系統有額外的成本,但生成隨機鹽並儲存它們有什麼好處呢?

在問這個問題時,我被提示這個問題:Use of salt to hash a password這部分證實了我的假設。如果我沒有立即確認答案,請不要私信,我想在確認之前看看那裡是否有不同的意見。

簡而言之,一種獨特的鹽殺死了彩虹桌。此外,您需要強制您的使用者建構良好的密碼,如diceware和具有良好參數的良好密碼散列算法。

那麼,儘管系統有額外的成本,但生成隨機鹽並儲存它們有什麼好處呢?

雜湊表,實際上是彩虹表,由於密碼搜尋空間的大小,這裡非常適合,需要為每個唯一的鹽構造。如果您使用全域鹽,那麼專門的攻擊者只需要建構一個表而不是多個表。

有趣的是,如果你要為每個使用者使用一個唯一的 nonce,為什麼攻擊者需要建立一個表?他們將只是蠻力搜尋,因為彩虹表沒有其他用途。這就是為什麼彩虹桌已經死了。

當然,無論他們是否建立了雜湊表,他們可以搜尋的內容都是有限的。例如,比特幣礦工達到 $ \approx 2^{92} $ 每年雙倍 SHA256 雜湊。因此,如果您強制使用者選擇高熵密碼,您將是安全的。

為了安全起見,請遵循通用指南;

  1. 每個使用者的唯一鹽
  2. 您需要教您的使用者選擇具有高熵的良好密碼,例如dicewareBip-39
  3. 密碼破解與密碼散列算法的速度和所需大小高度相關。您可以選擇 PBKDF2、Scrypt 或新的密碼雜湊競賽 Argon2 的獲勝者來對您的密碼進行雜湊處理。Argon2id 旨在使用大記憶體來通過使用大記憶體來減少 GPU 類型的攻擊。您需要設計您的系統,使每個使用者的密碼散列大約需要 1 秒。這可能相當於 PBKDF2 的 100 萬次迭代。在這種情況下,您將攻擊者的速度減慢了 100 萬次。
  4. 還使用不儲存在數據庫中但在增加攻擊者工作的應用程序伺服器中的辣椒。在某些情況下可能會有所幫助。特別是常見的攻擊是對數據庫的注入攻擊。

#2 與 #3

hash( global_salt + username + password ) vs hash( random_salt + password )

#3 和 #2。看起來很安全,因為每個使用者的使用者名都是唯一的,這將使全域鹽成為每個使用者的隨機鹽。但仍然非標準且未經測試。強制使用高熵密碼並使用良好的密碼散列機制是必要的。攻擊總是變得聰明。也許攻擊者可以將使用者名視為密碼的一部分,並嘗試以這種方式對其進行攻擊。這可能需要對實際數字進行計算。

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