如何從一個密碼派生兩個密鑰
從一個使用者輸入的密碼或密碼生成兩個獨立的對稱密鑰的最佳方法是什麼?同時使用 scrypt 和 pbkdf2 會實現這一點嗎?
是的,scrypt 實現了這一點。Scrypt 具有可變長度的輸出,因此只需生成所需的輸出即可。例如,您可以要求它提供 256 位的輸出,然後將前 128 位用於一個密鑰,將第二個 128 位用於另一個密鑰。
雖然 PBKDF2 也有可變長度輸出,但我不建議您以相同的方式使用它。它有一個微妙的缺點/弱點,如果您要求它生成多個輸出塊,它會稍微降低其可用的安全性。相反,我建議您像這樣使用 PBKDF2:
Kt = PBKDF2(..., passphrase, salt, n, 128) (K1, K2) = PBKDF2(..., Kt, salt, 1, 256)
換句話說,使用 PBKDF2 進行大量迭代(選擇 $ n $ 要大)生成一個 128 位的臨時密鑰 $ Kt $ ; 然後再次使用 PBKDF2 進行拉伸 $ Kt $ 成 256 位的偽隨機輸出,並用它來形成密鑰。
只要求 PBKDF2 給你 256 位的輸出有什麼問題?事實證明,由於一個微妙的問題,這可能會讓攻擊者獲得 2 倍的加速。或者,另一種思考方式:它迫使合法使用者做的工作量是他們應該做的兩倍,這意味著你不能把迭代計數推到你應該做的那樣高,所以你得到的安全性比你應該擁有的要弱得到。這篇 Ars Technica 文章從高層次上描述了這個微妙的問題;一篇部落格文章有更多的技術細節,1password 的解釋也是如此。
基本上,問題在於使用 PBKDF2,想要測試對您密碼的猜測的攻擊者可以僅生成 256 位輸出的前 128 位,其速度是生成整個輸出的兩倍,而前 128 位可能就足夠了來驗證猜測是否正確。Scrypt 沒有這個問題(當與典型參數一起使用時),所以使用 scrypt,你可以只要求它提供 256 位,你會沒事的。
不要試圖同時使用兩者。不需要同時使用 scrypt 和 PBKDF2;如果您同時使用兩者(scrypt 生成一個密鑰,PBKDF2 生成另一個),那麼您將引入上述相同的微妙弱點,只是形式略有不同。
**底線推薦。**如果這聽起來太複雜:只需使用 scrypt,並要求 scrypt 提供盡可能多的輸出。您可以忽略所有其他內容。