組合兩個鍵
將兩個大小為k(k ≤ 512 位)的“隨機”密鑰X和大小為 512 位的**Y組合到一個大小為k的密鑰Z中的最安全方法是什麼?結果Z將用於使用各種對稱密碼(最常見的是 CBC 模式下的 AES-256)或 HMAC 密鑰(最常見的是 SHA1 和 SHA256)進行加密/解密。
有兩個不同的案例:
- 單個Y將與單個X(大小為 512 位)組合,生成的Z將被多次使用
- 單個Y將使用不同的**X -es(具有可變的未知大小或各種大小)多次重複使用,並且將使用生成的Z -s
我知道簡單的 XOR-ing 不是一個好主意,因為在情況 2 中。如果單個X + Z對會受到損害,那麼攻擊者也將知道Y。
目前我認為可以在X ||上使用散列函式 (SHA-512) Y(|| 表示連接)和輸出的前k位可用作Z。我仍然沒有選擇此解決方案的唯一原因是因為我希望盡可能少地失去密鑰X的熵(並且由於雜湊函式中的衝突,可能會失去一些熵)。
另一個想法是在X上使用對稱密碼,並將Y用作密鑰(很可能是 CBC 模式下的 AES-256,而 IV 將輸出的前k位作為Z)。該解決方案的唯一優點是,如果X的長度為 256 或 512 位,則(由於對稱密碼的雙射性質)不應失去熵。
我想對此發表一些意見,可能有一些標準的解決方案/方法嗎?
密鑰派生功能可讓您從其他人那裡派生密鑰。在這種情況下,我將使用HKDF,這意味著以預定義的方式使用 HMAC。
你的關鍵材料就是鑰匙 $ X $ 和 $ Y $ ,因此您可以將它們連接起來以獲得 HKDF-Expand 的 PRK。然後輸出鍵將是 $ \operatorname{HMAC}(X||Y, \text{info} || \text{0x01}) $ ,如果 HMAC 的大小足夠長。如果不是,則按照2.3中所述連接迭代的 HMAC 。
資訊字元串應該用於自定義要從相同的密鑰派生的每個不同的密鑰 $ X $ 和 $ Y $ . 您不應該為例如 AES 和 HMAC 重複使用密鑰。
甚至 HMAC-SHA-1 在這裡也應該是安全的,但是使用 SHA-256,您可以使用單個輸出塊來派生 AES-256 的密鑰。如果您出於某種原因需要更長的密鑰(例如 Blowfish),您甚至可以使用 SHA-512。
我仍然沒有選擇此解決方案的唯一原因是因為我希望盡可能少地失去密鑰 X 的熵(並且由於雜湊函式中的衝突,可能會失去一些熵)。
如果你得出一個 $ n $ -位密鑰 $ n $ -bit(完全隨機)密鑰,在執行它時,您在碰撞中損失的熵少於一點 $ n $ 位 HMAC。什麼時候 $ n \ge 128 $ 這根本不重要。此外,如果您派生一個密鑰 $ k\ll n $ 從一個位 $ n $ -bit 密鑰,您不會失去任何熵。