使用散列函式作為密鑰派生函式有多安全?
我正在開發一個個人項目,我有以下需求:給定一個隨機生成的種子(具有足夠的熵)我需要生成一個數字 $ x $ Ed25519 密鑰對。不儲存這些密鑰對。因此,我需要隨時用這個種子生成完全相同的密鑰對。
為了實現這一點,我有以下算法來生成一個地址號 $ y $ :
- 我連接種子和 $ y $ 我計算了 SHA-3 雜湊:
hash = SHA-3(seed+y)
.- 使用這個雜湊,我生成了一個 Ed25519 密鑰對,使用這個雜湊作為種子:(
keyPairY = new ed25519KeyPair(hash)
它ed25519KeyPair
需要nacl.sign.keyPair.fromSeed
一個種子作為它的參數)。這種算法有多安全?
這是合理的,只要(a)你的意思是種子和索引的一些唯一編碼 $ y $ 當你說
seed + y
,(b)你永遠不會將相同的種子和索引用於其他目的,並且(c)你選擇了 SHA3-256、或 SHAKE128-256 或 SHAKE256-256,並且你使用的是標準 Ed25519 32 字節預-master 秘密種子作為秘密。對於 (a):如果,例如,種子總是正好 32 個字節,您可以使用連接。如果種子的長度可能不同,您可以考慮連接 $ n \mathbin\Vert \mathit{seed} \mathbin\Vert y $ 在哪裡 $ n $ 是種子中的字節數,因此不存在 $ (\mathit{seed}, y) $ 這可能會被串聯混淆。請注意,答案特定於上述 SHA-3 函式。這不適用於可能被稱為散列函式的*所有內容。*GHASH 肯定不是這樣。它甚至不適用於 SHA-256,除非您對種子和索引施加額外的約束,即它們的長度都是固定的,或者它們的編碼是長度前綴的。這是因為給定 $ h = \operatorname{SHA256}(\mathit{seed} \mathbin\Vert y) $ , 很容易計算 $ \operatorname{SHA256}(\operatorname{pad}(\mathit{seed} \mathbin\Vert y) \mathbin\Vert y’) $ 在不知道種子的情況下——對 SHA-256 的標準長度擴展攻擊。如果您必須將 SHA-256 與可變長度的種子和索引一起使用(聽起來您不需要,但其他路人可能會閱讀此內容),如果不是 HKDF,將其與 HMAC 一起使用來製作 PRF 可能會更簡單.
通常,您應該考慮使用為此目的量身定制的東西,除非您有排除它的限制: KMAC,如果您想要基於 Keccak 的 PRF;HKDF,如果您必須使用 SHA-2 並且您想要應用程序和目的標籤的結構化輸入。