[英]Understanding how Rfc2898DeriveBytes works
我正在為我們數據庫中的敏感數據編寫一個加密序列。
目前我正在使用基於 UserId 的 GUID,並將其放入哈希中。 然后,我通過 Rfc2898DeriveBytes 運行哈希以獲取用於使用 Rijndael 函數加密數據的密鑰和 IV。
我的代碼如下所示:
var salt = new byte[] { 1, 2, 23, 234, 37, 48, 134, 63, 248, 4 };
const int iterations = 1000;
using (var rfc2898DeriveBytes = new Rfc2898DeriveBytes(GenerateHash("2525"), salt, iterations)) {
_key = rfc2898DeriveBytes.GetBytes(32);
_iv = rfc2898DeriveBytes.GetBytes(16);
}
然后我傳遞 _key 和 _iv 來解密或加密數據。 我的目標是讓每個用戶在每個會話中始終可以訪問他們的唯一密鑰。 話雖如此,什么可以隨機化並且仍然保持這個功能? 我是否總是必須使用相同的鹽和相同的 IV 來獲取我想要的數據?
Rfc2898DeriveBytes
是 PBKDF2 的實現。 顯然,RFC 2898 是對定義此基於密碼的密鑰派生函數的標准的參考。 請注意,該標准比 KDF 更廣泛; 它的全稱是“PKCS #5: Password-Based Cryptography Specification, Version 2.0”。
PBKDF2 是定義 PBKDF / PBKDF1 的 PKCS#5 v1 的繼承者。 1 是在 PBKDF2 產生后才添加的。 PasswordDeriveBytes
類是 PBKDF1 的實現。 它不應該再使用了,因為 KDF 已經過時了,也因為微軟嚴重搞砸了實現; 如果請求超過底層哈希的輸出 - SHA-1 所以 20 個字節 - 它可能會重復輸出密鑰材料。
除了用作 KDF 之外,PBKDF2 還可以用作密碼散列函數,其中散列而不是密碼存儲在數據庫中。 這樣可以驗證密碼,而即使攻擊者檢索到哈希數據,也無法輕松檢索密碼。 這在包含 2.1 版本協議的后續RFC 8018中進行了描述。
在內部,PBKDF2 只是對密碼和鹽的哈希函數的重復。 迭代次數是工作因子; 它指定了在計算一個哈希值之前你(和對手)需要做多少工作。 鹽確保彩虹表攻擊是不可能的,並且(不同用戶的)相同的密碼不會導致相同的哈希。
由於設計錯誤,如果需要多個哈希輸出,則需要重復全部工作,因此不建議從中請求比哈希函數的輸出更多的數據。 在這種情況下,最好使用另一種方法來擴展輸出密鑰材料(字節),例如 HKDF-Expand。
對問題中代碼的觀察:
GenerateHash
方法是假的, Rfc2898DeriveBytes
會為你做這個;只是一個一般提示,僅使用生成的密鑰來加密由安全隨機函數創建的數據特定密鑰。 然后,您甚至不需要擔心 IV,您可以通過解密數據特定密鑰並使用新密鑰對其進行加密來“重新加密”。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.