當您擁有 PRF 時,您真的需要 KDF 嗎?
我的理解是,KDF 就像 PRF,只是它有一個“提取”熵的初步步驟。因此,當熵不均勻時需要它(例如,ECDH 的輸出模數不是 2 的冪,因此如果表示為位串,則不均勻)。
然而,我不確定是否有現代對稱算法需要秘密均勻分佈。當然,它們的安全性可以用一個統一的密鑰來定義,但是使用 KDF 感覺有點像作弊,因為沒有添加新的熵,而且速度也不慢。我錯過了什麼嗎?
當您擁有 PRF 時,您真的需要 KDF 嗎?
也許。
PRF 的安全合約要求密鑰是一個統一的隨機位串。如果你有一個 DH 秘密或一個 diceware 片語,那麼你所擁有的不是一個比特串的統一隨機,因此你的契約義務沒有得到滿足,PRF 可能沒有提供任何安全保障。 您需要一些更強大的東西來將 DH 秘密或 diceware 密碼片語散列成一個統一的隨機位字元串,這就是“提取”步驟所做的。
這是一個例子。讓 $ F_k $ 成為 PRF 並讓 $ H $ 成為一個隨機的神諭。定義$$ F’{x,y}(s) := F{H(u)}(s), \quad u = (y^2 - x^3 - 7) \bmod p, $$在哪裡 $ p = 2^{256} - 2^{32} - 977 $ . $ F’ $ 也是一個 PRF,因為當 $ (x, y) $ 在 512 位字元串中均勻分佈,碰撞機率 $ u $ 是小。但如果 $ (x, y) $ 是 secp256k1 上的 DH 密鑰協議的結果,則 $ y^2 \equiv x^3 + 7 \pmod p $ 所以 $ u $ 總是零,因此 $ F’{x,y}(s) = F{H(0)}(s) $ 對所有人 $ x $ 和 $ y $ ——也就是說,DH密鑰協議根本不影響輸出,所以系統沒有提供任何安全性!
**如果您已經擁有一個統一的隨機位串作為主密鑰,並且您只需要從中派生具有不同標籤的子密鑰,那麼您只需要一個 PRF ,而“擴展”步驟實際上就是一個 PRF . 例如,如果你仔細觀察 HKDF,你會發現$$ \operatorname{HKDF-Expand}_k(L) = \operatorname{HMAC-}!H_k(L \mathbin| \mathtt{0x01}), $$如果所需的輸出大小與輸出大小匹配 $ H $ ; 如果請求更多字節,只需重複呼叫 $ \operatorname{HMAC-}!H $ 帶有連續的計數器和前面的塊 $ L $ ,並連接輸出。你當然可以用 $ \operatorname{HMAC-}!H $ 您最喜歡的 PRF,例如鍵控 BLAKE2b、KMAC128、KangarooTwelve、Kravatte、前綴鍵控 Gimli-Hash 或 ChaCha $ \circ $ Poly1305,雖然它不是 HKDF,但它同樣適用於派生子密鑰。
我的理解是,KDF 就像 PRF,只是它有一個“提取”熵的初步步驟。因此,當熵不均勻時需要它(例如,ECDH 的輸出模數不是 2 的冪,因此如果表示為位串,則不均勻)。
正確:將 extract-with-salt 和 expand-with-label 的概念收集到一個術語 KDF 中的目的是,這兩個步驟通常很接近——你有一個 DH 秘密,或者一個主 diceware 片語,這不是位串中的統一但具有高熵,並且您希望從中派生許多秘密密鑰以用於不同的標記目的。
然而,我不確定是否有現代對稱算法需要秘密均勻分佈。當然,它們的安全性可以用一個統一的密鑰來定義,但是使用 KDF 感覺有點像作弊,因為沒有添加新的熵,而且速度也不慢。我錯過了什麼嗎?
許多密碼原語的安全合約要求輸入是統一隨機的。違反契約,安全可能會蒸發。顯然,您可以在統一隨機密鑰下通過偽隨機函式選擇輸入——如果這破壞了組合,那麼僅使用組合就可以作為偽隨機函式的區分符。但目前尚不清楚是否可以在下游密碼系統中利用高度結構化的密鑰(如特定曲線上點的位編碼)。 也許你會被上面人為設計的 secp256k1 範例中的不良互動所困擾;也許你不會。 使用 HKDF-Extract 或以其他方式對輸入進行散列處理,使這些問題變得毫無意義因此您甚至不必考慮它們。
然而,我不確定是否有現代對稱算法需要秘密均勻分佈。當然他們的安全性可以用一個統一的密鑰來定義,
$$ … $$
雖然人們通常說對稱算法的密鑰必須隨機均勻地選擇,但嚴格來說這是錯誤的。數學實際上說的是,如果密鑰是隨機統一選擇並保密的,那麼密碼方案具有這樣那樣的安全屬性。這並不排除系統可以使用其他一些非統一的密鑰選擇方法來保證安全。(“如果 P 則 Q”並不意味著“如果 Q 則 P”。)
我們需要密鑰推導步驟的原因是從偽隨機分佈(即無法有效地區分均勻隨機分佈的分佈)中採樣的密鑰就是這樣一種方法。這些密鑰嚴格來說不是均勻隨機的,但正如 Squeamish Ossifrage 順便指出的那樣,如果當我們使用 KDF 為其生成密鑰時,對手可以利用這一事實來攻擊該方案,那麼這可以轉化為對 KDF 的攻擊它本身——顯示生成的密鑰實際上可以與均勻隨機區分開來。
或者更簡單地說,偽隨機密鑰不是統一隨機密鑰,但可以替代它們,這就是我們使用它們的原因——它們使“如果密鑰是統一隨機的,那麼
$$ security property $$” 陳述間接繼承。用非常不雅的英語:
如果是這樣的話:
- 如果密鑰是統一隨機的
- 然後$$ security property $$,
然後:
- 如果密鑰是偽隨機的
- 然後$$ security property $$.
$$ … $$但是使用 KDF 感覺有點像作弊,因為沒有添加新的熵,而且速度也不慢。我錯過了什麼嗎?
ECDH 是一個場景,我們有一個共享的秘密值,它有大量的熵。這意味著您沒有理由要為其“添加熵”或減慢密鑰派生速度——這表明您在基於密碼的 KDF(這些是常見主題)和非基於密碼的 KDF 之間混淆了.
但是正如您所說,ECDH 秘密不是偽隨機的,因為它與位串上的均勻分佈無法區分。這意味著如果您直接將其用作對稱密鑰,您將無法利用上述安全參數。