Key-Derivation

為什麼 openssl 從密碼中派生 IV?

  • September 14, 2017

來自https://wiki.openssl.org/index.php/Manual:Enc(1)

當使用其他選項之一指定密碼時,將從此密碼生成 IV。

為什麼 OpenSSL 會這樣做?我的期望是每次呼叫 OpenSSL 時都會在輸出消息中生成和編碼一個唯一的 IV。解密時,OpenSSL 會提取 IV 並使用它。

是否有任何理由從密碼中派生 IV?這樣做是否安全?您每次使用密碼時不是使用相同的 IV 嗎?如果要與加密密鑰配對,使用 IV 的意義何在?

如果您仔細閱讀您引用的手冊頁,您會發現以下幾行:

-我們跳

do not use a salt 

-鹽

use salt (randomly generated or provide with -S option) when encrypting (this is the default).

如果密鑰是從密碼派生的,則應始終使用 -salt 選項,除非您希望與以前版本的 OpenSSL 和 SSLeay 兼容。

如果沒有 -salt 選項,則可以對密碼執行有效的字典攻擊並攻擊流密碼加密數據。原因是沒有鹽,相同的密碼總是生成相同的加密密鑰。當使用 salt 時,加密數據的前 8 個字節為 salt 保留:它在加密文件時隨機生成,並在解密時從加密文件中讀取。

綜上所述,我們了解到:

  • 您應該使用隨機salt,它在密鑰派生過程中使用(從密碼計算加密密鑰和 IV)
  • 如果您使用鹽,密鑰和 IV 以及因此密文將不是確定性的
  • 使用隨機鹽是openssl enc的預設行為

您可以通過執行輕鬆檢查

echo foo |openssl enc -aes-128-cbc -out encrypted -nosalt

echo foo |openssl enc -aes-128-cbc -out encrypted

在第一種情況下,輸出將是 16 字節長(一個 AES 塊),在第二種情況下會更長,因為必須儲存鹽。

在 OpenSSL 中,如果使用 enc 命令 ( enc.c ),則從密碼生成 IV 的同時執行密鑰的派生(通過函式EVP_BytesToKey: source)。正如他們在這裡所說:

EVP_BytesToKey(3) 函式為基於密碼的加密提供了一些有限的支持。仔細選擇參數將提供與 PKCS#5 PBKDF1 兼容的實現。但是,新應用程序通常不應該使用它(例如,更喜歡 PCKS#5 中的 PBKDF2)。

因此,如果在派生中使用了適當的鹽,則從密碼中派生 IV 是安全的(參見RFC 2898)。如果每次都選擇隨機鹽,則每次使用密碼時都不會使用相同的 IV。

此外,如果 salt 已經提供了足夠的隨機性,那麼從 KDF 的相同輸出中派生密鑰和 IV 也是安全的。也就是說,鹽的大小應該已經足以確保攻擊者難以預先計算出密碼字典的所有可能密鑰。因此,僅僅為了增加計算所有可能對(key,IV)的負擔而將密鑰和 IV 推導分開是不合理的。


我的下一個問題是,為什麼他們不將 PBKDF2 用於帶密碼的 enc 命令?

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