簡體   English   中英

了解 Rfc2898DeriveBytes 的工作原理

[英]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。


對問題中代碼的觀察:

  1. GenerateHash方法是假的, Rfc2898DeriveBytes會為你做這個;
  2. 您應該使用比 UID 更難預測的東西來創建密鑰; 數據不應直接提供給攻擊者,因為這將完全違背 PBKDF2 的目的;
  3. 如果您想對多個加密操作使用同一組 UID + salt + 迭代,那么您應該生成一個隨機 IV 並將其添加到密文中,非隨機 IV 完全違背了 IV 的目的;
  4. 您可以更改鹽以獲取多個密鑰,但您必須通過 PBKDF2 函數進行每次加密。

只是一個一般提示,僅使用生成的密鑰來加密由安全隨機函數創建的數據特定密鑰。 然后,您甚至不需要擔心 IV,您可以通過解密數據特定密鑰並使用新密鑰對其進行加密來“重新加密”。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM