如何安全地組合多個熵源?
假設我有 $ n $ 使用已知安全的方法單獨生成的安全 32 位密鑰。例如,其中一個可能是使用經過驗證的 CSPRNG 生成的。另一個可能是使用 PBKDF2 生成的。
現在,我想將所有這些密鑰組合在一起,形成一個新密鑰,我可以用它來加密和解密數據。
重要的是我想要求所有密鑰都存在才能執行加密和解密。
我想知道的是,結合這些密鑰並保持最高級別的安全防範攻擊的最佳方式是什麼?
例如,我可以連接所有 32 位密鑰,然後再次通過 PBKDF2 執行它們:
# pbkdf2(key, salt, iterations, derived_key_length) # Also, "a + b" indicates concatenating a + b as strings, i.e. "hello" + " world" = "hello world" new_key = pbkdf2(key1 + key2 + key3, some_salt, 10000, 32)
或者,我可以將它們中的一些連接到鹽中,而不是連接它們:
new_key = pbkdf2(key1, key2 + key3, 10000, 32)
或者,我可以迭代地執行 pbkdf2:
temp_key = pbkdf2(key1, key2, 10000, 32) new_key = pbkdf2(key3, temp_key, 10000, 32)
或者,我可以將它們全部連接起來並散列它們:
new_key = sha1(key1 + key2 + key3)
或者,我可以使用前一個散列的連接版本迭代地散列它們:
a = sha1(key1) b = sha1(a + key2) new_key = sha1(b + key3)
或者,我可以使用上述方法之一生成雜湊,然後通過 PBKDF2 執行該雜湊:
hash = sha1(key1 + key2 + key3) new_key = pbkdf2(hash, some_salt, 10000, 32)
或者,我可以將它們全部異或:
new_key = xor(xor(key1, key2), key3)
或者,將它們全部異或,然後通過 pbkdf2 等執行。
顯然,有很多方法可以組合這些密鑰來生成新的安全密鑰。
有這方面的前期工作嗎?最好和最安全的方法是什麼?
如果上述任何一種方法都不安全,您能解釋一下原因嗎?
PS作為這個問題的另一個方面,我很好奇“密碼”或“鹽”是否或多或少是放置熵的安全位置。例如,以下兩者是否同樣安全?
new_key = pbkdf2(key1 + key2, key3, 10000, 32)
和
new_key = pbkdf2(key1, key2 + key3, 10000, 32)
如果您的密鑰加在一起具有足夠的熵來支持您所需的安全級別,那麼HKDF(紙)在這裡是一個保守的解決方案,因為它假設輸入的密鑰材料
HKDF-extract
可能不是均勻分佈的。在您的情況下使用它的最保守方法是將您的鍵的串聯作為
IKM
(“輸入鍵控材料”)參數提供給HKDF-extract
,並且不要使用可選的鹽。然後PRK
直接使用結果,或者作為HKDF-expand
函式的進一步輸入。如果您確信您的輸入與統一隨機且相互獨立無法區分,則使用它的一種不太保守的方法是跳過將
HKDF-extract
連接輸入直接提供給HKDF-expand
.