Aes

本方案的安全性

  • January 1, 2016

我正在開發一個軟體,但我不確定它是否完全安全。

我有 22 Mb 的數據要加密多次使用,

隨機 IV(使用 OpenSSL lib 中的 RAND_bytes 生成)

和密碼 $ key = SHA3_{256}(PBKDF2(salt, password, 256000, SHA2-256)) $ .

來自 Qt QCryptographicHash、PBKDF2 和SHA_256OpenSSL 的 SHA3_256,salt 也是由RAND_BYTE256 位長生成的。

現在我想知道你的意見,如果這個方案是安全的:

XOR 鍵和 IV 一起:

$$ encryptionKey = IV \oplus key\ $$ 加密 IV:

$$ firstBlock=E_{AES-EBC-256}(key, IV) $$ 加密數據:

$$ secondBlock = E_{AES-GCM-256}(encryptionKey, IV, data) $$ 接著:

$$ output << firstBlock\ output << secondBlock $$ 我不太確定這部分 $ E_{AES-GCM-256}(IV \oplus key, IV, data) $ .

我非常感謝您對此的看法。

回答完整的問題相當困難,但我會盡力回答。


您嘗試使用 IV 導出數據加密密鑰,因為您認為 IV 可能被過度使用。

NIST SP 800-38D 第 8.3 節狀態(對於不重複的機率 $ 2^{-32} $ ):

認證加密函式的總呼叫次數不得超過 $ 2^{32} $ ,包括所有 IV 長度和具有給定密鑰的經過身份驗證的加密函式的所有實例。

太好了,所以除非你呼叫 GCM 超過 40 億次(短期),那麼你應該沒問題,你可能不需要任何特殊的構造。


假設您不想限制 GCM 呼叫的數量。在這種情況下,您為每個加密派生一個密鑰。您可以使用基於密鑰的密鑰派生函式或 KBKDF。您可以使用的最好的可能是 HKDF。HKDF 也接受鹽,並且能夠根據需要從輸入中生成盡可能多的位。因此,您可以使用以下構造:

  1. $ salt = random() $
  2. $ seed = PBKDF2(salt, password, 256000, SHA2-256) $
  3. $ key = HKDF(seed, \text{“key”}) $
  4. $ iv = HKDF(seed, \text{“iv”}) $
  5. $ (ct, tag) = E_{AES-GCM-256}(key, iv, data) $
  6. $ output = encode(salt, (ct, tag)) $

現在說您不想為每個文件執行那些 256000 次迭代,並且您想一次加密/解密多個文件,那麼您可以執行以下操作:

  1. $ salt = random() $
  2. $ seed = PBKDF2(salt, password, 256000, SHA2-256) $
  3. $ salt_2 = random() $
  4. $ key = HKDF(seed, salt_2, \text{“key”}) $
  5. $ iv = HKDF(seed, salt_2, \text{“iv”}) $
  6. $ (ct, tag) = E_{AES-GCM-256}(key, iv, data) $
  7. $ output = encode(salt, salt_2, (ct, tag)) $

因為 HKDF 也可以使用鹽。對於每個文件,重複步驟 3 到 6。

一個技巧是只使用 HKDF-expand 並為密鑰IV 生成 512 位。如果 HKDF 不可用,也可以使用其他更簡單的 KDF,例如 KDF1 或 KDF2。


至於你的方案,我看到了一些缺點。

  1. 對 SHA-3 的額外呼叫是虛假的;
  2. GCM 的 IV 最好設置為 96 位(12 字節),但 IV 的 XOR 和加密似乎建議使用 128 位的 IV;
  3. 密鑰和 IV 的 XOR’ing 不是安全密鑰派生函式;
  4. 密鑰長度現在被限制在 IV 的大小或引入額外的複雜性;
  5. 不建議為不同的相關算法重用派生密鑰。

這裡3和5的組合是最大的問題;您必須證明不安全的密鑰派生不會妨礙 GCM 算法的安全性。這不是你應該想做的事情。


與往常一樣,建議使用現有的協議和庫;有很多安全的可用。

引用自:https://crypto.stackexchange.com/questions/31611