為什麼在 PBKDF2 中鹽只使用一次,而密碼卻經常使用?
PBKDF2 的目的是從主密碼 (PW) 和鹽創建派生密鑰 (DK),通常使用 HMAC-SHA256 之類的函式。我讀過鹽應該盡可能隨機。但如果是這樣的話,為什麼它的作用那麼小?
我會讓方程式自己說話,從 HMAC-SHA256 開始:
$$ \def\op{\operatorname}\def\0#1#2#3{\text{0×#2#3}} \op{HMAC-SHA256}( PW, m ) = \op{SHA256}( K_o ∥ \op{SHA256}( K_i ∥ m ) ) $$ 在哪裡 $$ \begin{align*} K &= \begin{cases} PW &\textrm{if } \op{bytes}( PW ) = 64 \newline \op{SHA256}( PW ) ∥ [\0x00]{32} &\textrm{if } \op{bytes}( PW ) > 64 \quad \textrm{ (32 zero bytes)} \newline PW ∥ [\0x00]{64-\op{bytes}(PW)} & \textrm{if } \op{bytes}( PW ) < 64 \end{cases} \newline K_i &= K ⊕ [\0x36]{64} \newline K_o &= K ⊕ [\0x5c]{64} \newline \end{align*} $$ 現在 PBKDF2:
$$ \begin{align*} DK &= T_1 ∥ T_2 ∥ … ∥ T_{\op{len}(DK)/\op{len}(T_i)} \newline T_i &= U_1^i ⊕ U_2^i ⊕ … ⊕ U^i_{\text{iterations}} \newline U^i_1 &= \op{HMAC-SHA256}( PW, \op{salt} ∥ \op{INT32}( i ) ) \newline U^i_n &= \op{HMAC-SHA256}( PW, U^i_{n-1} ) \end{align*} $$ 但是請注意如果將兩者結合起來會發生什麼:
$$ \begin{align*} U^i_1 &= \op{SHA256}( K_o ∥ \op{SHA256}( K_i ∥ \op{salt} ∥ \op{INT32}( i ) ) ) \newline U^i_2 &= \op{SHA256}( K_o ∥ \op{SHA256}( K_i ∥ \op{SHA256}( K_o ∥ \op{SHA256}( K_i ∥ \op{salt} ∥ \op{INT32}( i ) ) ) ) ) \newline & \dots \end{align*} $$ 或者在虛擬碼中:
$$ \begin{align*} &T[i] = 0 \newline &U = \op{salt} ∥ \op{INT32}(i) \newline &\text{for } n = 1 \text{ to }c: \newline &\qquad U = \op{SHA256}( K_i ∥ U ) \newline &\qquad U = \op{SHA256}( K_o ∥ U ) \newline &\qquad T[i] = T[i] ⊕ U \newline &\text{next }n \newline \end{align*} $$ 所以鹽在每個輸出塊中只使用一次,而主密碼在每次迭代中使用兩次(形式為 $ K_o $ 和 $ K_i $ )。我知道雪崩效應意味著初始雜湊輸入的微小變化會對雜湊輸出產生重大影響,但是在最終結果中引入盡可能多的熵難道沒有意義嗎?
**摘要:我不知道為什麼必須這樣。**在實踐中,我認為沒有必要在每次迭代中都注入密碼。據我所知,如果您僅在第一次迭代的輸入中使用鹽和密碼,然後只是重複多次散列結果而不進一步輸入密碼,我認為構造仍然是安全的(在實踐中) .
那麼,如果 PBKDF2 對安全性而言並非絕對必要,為什麼要這樣做呢?我不知道。我只能推測——你應該對我的推測持保留態度。也就是說,我的猜測是,通過在每次迭代中使用密鑰,您可以獲得一些更好的可證明安全性結果。
技術推測:與安全證明有關。 特別是,使用 PBKDF2,可以證明如下語句:如果 HMAC-SHA256 是安全 PRF,並且如果密碼是全熵全強度加密密鑰,那麼 PBKDF2(password, salt) 是一個安全的加密密鑰。如果第一次迭代後的每次迭代都使用裸散列而不是 HMAC PRF,則沒有這樣的語句可用;您需要做出更強有力的假設,例如在隨機預言模型中工作(即假設散列在各個方面都是完美的)。
也就是說,可證明安全性的差異對我來說可以忽略不計。您可以證明 PBKDF2(沒有隨機預言機模型)的安全聲明並不是很令人興奮。PBKDF2 主要用於從非全熵的可記憶密碼中派生密鑰,並且上述安全證明未涵蓋這種情況。所以,據我所知,我不知道為什麼 PBKDF2 被設計為將密碼注入算法的每次迭代中。
**標準免責聲明:不要自己動手。**請不要將此文章作為修改 PBKDF2 和使用您修改後的 PBKDF2 版本的理由。那將是一件相當冒險的事情。即使我們想不出為什麼必須按照它的方式設計 PBKDF2 的任何有力理由,使用標準原語仍然更安全。PBKDF2 已經過嚴格審查,誰知道呢,也許這個變體有一些我沒有想到的問題。
使用密鑰兩次的並不是真正的 PBKDF2。PBKDF2 使用 HMAC,而 HMAC 恰好通過兩次使用密鑰來工作。
更具體地說,PBKDF2 實際上是一種通用結構,它使用加密偽隨機函式(PRF) 來完成一些內部工作。此處使用的 PRF 是鍵控HMAC。HMAC 結構本身使用兩個從原始密鑰單獨派生的密鑰。從問題中包含的 PBKDF2 描述中, $ K_o $ 和 $ K_i $ 值分別是外部和內部 HMAC 密鑰。
這會將問題轉移到:“為什麼 HMAC 使用兩個密鑰”?這在其他問題中得到解決:
另一個與相關答案密切相關的問題:雜湊函式 in PBKDF2。