Key-Derivation
PasswordDeriveBytes 背後的算法是什麼?
PasswordDeriveBytes
Microsoft 在該類中創建了 PBKDF1 的實現。但是,它可以生成比 PBKDF1 更多的字節,而 PBKDF1 受限於底層雜湊函式生成的字節數。微軟的這個專有擴展是如何定義的?
Microsoft 實現中的密碼
P
首先使用 UTF-8 進行編碼。迭代次數c
預設為100,雜湊算法Hash
SHA-1。輸出與 PBKDF1 相同,最大輸出大小為 PBKDF1,即散列的輸出大小。之後,倒數第一個散列以計數器為前綴(作為包含使用 ASCII 編碼的十進制數字的字元串)並再次散列以產生輸出。如果
GetBytes
被多次呼叫,它只會從流中返回下一個輸出字節。請注意,此描述並未描述 Microsoft 與早期 Windows 作業系統一起提供的損壞的實現。那些包含一個錯誤
GetBytes
,如果它被呼叫兩次或更多次,可能會導致方法的輸出重複。下面是對該算法的更正式的描述。它擴展了 RFC 2898 第 5.1 節中 PBKDF1 的定義。
PBKDF1_MS (P, S, c, dkLen) Options: Hash underlying hash function Input: P password, an octet string S salt, an eight-octet string c iteration count, a positive integer dkLen intended length in octets of derived key, a positive integer, bounded to 100 times the output size of Hash Output: DK derived key, a dkLen-octet string Steps: 1. If dkLen > 100 * Hash output "derived key too long" and stop. 2. Apply the underlying hash function Hash for c iterations to the concatenation of the password P and the salt S, apply the Microsoft extension by hashing the concatenation of an encoded counter and the output of the hash produced for iteration c - 1, then extract the first dkLen octets to produce a derived key DK: T_1 = Hash (P || S) , T_2 = Hash (T_1) , ... T_c = Hash (T_{c-1}) , R_1 = T_c , R_2 = Hash (Ctr(1) || T_{c-1}) , ... R_n = Hash (Ctr(n-1) || T_{c-1}) , R = R_1 || R_2 || ... || R_n DK = R<0..dkLen-1> 3. Output the derived key DK. The Ctr function converts the given number to a decimal representation in ASCII.
強烈建議您使用
RFC2898DeriveBytes
實現 PBKDF2 的替代。如果 PBKDF2 的輸出需要超出底層雜湊的輸出大小,則建議使用基於密鑰的密鑰派生函式,例如 HKDF。如果您沒有實現,那麼只需對輸出和靜態大小的標識符進行雜湊處理,以創建派生鍵
SHA-256(master | identifier)
並根據需要從左側獲取盡可能多的字節。