Pbkdf-2

多執行緒 PBKDF2 或 javascript 替代方案

  • May 7, 2018

我在瀏覽器中使用 PBKDF2(不能使用 bcrypt,使用者的密碼可能 > 72 字節,或者任何數字)。PBKDF2 在 webworker 中執行,類似這樣

const key = PBKDF2_HMAC_SHA512.bytes(passphrase, salt, Math.pow(2,17), 64)

此密鑰用於加密要儲存在使用者本地儲存中的數據。現在我想知道,既然我已經在使用 webworker,為什麼不使用多個呢?我不能並行化它嗎?我能不能做類似的事情(簡化,實際上每個密鑰都是在一個單獨的網路工作者中生成的)

const key1 = PBKDF2_HMAC_SHA512.bytes(passphrase, salt1, Math.pow(2,17), 16)
const key2 = PBKDF2_HMAC_SHA512.bytes(passphrase, salt2, Math.pow(2,17), 16)
const key3 = PBKDF2_HMAC_SHA512.bytes(passphrase, salt3, Math.pow(2,17), 16)
const key4 = PBKDF2_HMAC_SHA512.bytes(passphrase, salt4, Math.pow(2,17), 16)
const key5 = new Uint8Array(64)
key5.set(key1)
key5.set(key2, 16)
key5.set(key3, 32)
key5.set(key4, 48)
const key = SHA_512.bytes(key5)

這不是更安全 4 倍嗎?或者更重要的是,我能否將每個 pbkdf2 實例的輪次減半,但最終仍能獲得 2 倍的安全性?如果我錯了,有人能指出我正確的方向來獲得更快/更安全的可並行化 kdf 嗎?

是的,這將提高安全性。事實上,您甚至不需要使用單獨的鹽。只需將執行緒號作為計數器與輸入鍵連接就足夠了:

輸入:k,要用 KDF 加強的短鍵
輸出:h,最終輸出雜湊

spawn_thread(h0 := slow_KDF(k || 0))
spawn_thread(h1 := slow_KDF(k || 1))
spawn_thread(h2 := slow_KDF(k || 2))
...
spawn_thread(h *n* := slow_KDF(k || *n* ))

wait_for_all_threads()

h := fast_hash(h0 || h1 || h2 || ... || h *n* )

然而,這並不是特別有效。每次將執行緒數量增加一倍(假設每個執行緒都是真正獨立的並且不共享任何資源),您就增加了相當於一點的安全性。添加到輸入的單個額外字節提供的難度相當於在具有 256 個獨立硬體執行緒的系統上執行它。假設您不會獲得超過 8 個並行 KDF 實例,那麼您將永遠不會將安全性提高超過 3 位……

相反,您應該使用記憶體硬的 KDF,防止攻擊者使用 GPU 或 ASIC 並行攻擊 PBKDF2。一個例子是 Argon2,除了可配置的記憶體量外,它本身還支持並行性。

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