Hash

用鹽散列密碼 - 為什麼要為每個人使用不同的鹽?

  • January 26, 2013

給定一個我們有使用者名和密碼的數據庫,我們希望通過散列來保護使用者的密碼。我們不應該在這個散列中只使用使用者名和密碼,因為從其他網站獲取使用相同散列函式的數據的人可能會得出相同的結果,從而知道我們的密碼。如果我們嘗試自己對密碼進行雜湊處理,很容易暴力破解整個數據庫並猜測所有密碼。在正常應用程序中,密碼使用隨機鹽進行雜湊處理,隨機鹽與密碼一起儲存,以防止密碼被輕易暴力破解。

但是,我們可以對數據庫中的每條記錄使用使用者名、密碼和相同的鹽。此選項將為每條記錄保存一個數據欄位,而使用者名和密碼的組合對於我們的整個數據庫來說是唯一的。這種解決方案是否與傳統的密碼散列方案一樣安全,或者它們是否存在一些我不知道的安全缺陷?

讓我們盡量避免隨機的每個密碼鹽。如果對 salt 的唯一要求是唯一的(良好的密碼雜湊方案就是這種情況),您將需要:

  • $ globalSalt $ 是一個秘密的隨機 32 字節字元串。
  • $ userId_n $ 是唯一的使用者標識符。

例如,您可以使用 $ HMAC $ - $ SHA256(globalSalt, userId_i) $ 為每個使用者生成鹽 $ i $ . 或者,使用 PBKDF2 或 scrypt,您可以連接 $ globalSalt $ 和 $ userId_i $ .

僅當您不允許使用者更改密碼時,此方案才能實現 salt 的唯一性。如果你這樣做了,salt 將是每個使用者唯一的,而不是每個密碼,所以如果有人更改了他們的密碼,他們的 salt 將保持不變。在這種情況下,如果在三個時間點發生數據庫洩漏,假設鹽是每個使用者唯一的,而不是每個密碼,攻擊者會獲得一些關於密碼的資訊(例如,如果使用者將密碼更改為相同的值.)

要使每個密碼的 salt 唯一,您還必須包含一些密碼更改計數器,您必須更新和儲存這些計數器,並與 $ userId $ . 為每個使用者儲存這個計數器違背了初衷,所以你可以有一個全域計數器,確保它永遠不會重複,在這種情況下你也可以刪除 $ userId $ 只需使用這個計數器 $ globalSalt $ .

如果 $ globalSalt $ 被洩露,攻擊者獲得的唯一優勢是他將能夠為目前和未來預先計算未來的雜湊值 $ userId $ s,這似乎不是很有用。

我們通過建構一個更複雜、更不安全的系統來避免生成和儲存隨機鹽。因此,正如其他人所說,使用隨機鹽而不是打擾實現自己的方案要簡單得多,也更安全。

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