使用自身(作為加密密鑰)加密密碼以將其儲存在不安全的媒體上有多安全?
我想將密碼安全地儲存在儲存中(假設在通常的未加密文件中)。
我使用這個密碼作為 AES 密鑰來加密自己(使用 AES-ECB)然後將它儲存在媒體上(密碼長度最多為 16 個字節)。
當使用者想要確認它的身份時,我用使用者輸入解密這個保存的加密內容並將其與相同的輸入進行比較,如果它們相等,則表示使用者已成功驗證。
知道我有兩個重要的問題:
- 這是一個正確的解決方案嗎?如果不是,為什麼不呢?
- 這是最好的解決方案嗎?如果不是,為什麼不呢?(請給我更好的建議)
我認為您正在尋找的是基於密碼的密鑰派生函式(PBKDF)。
您可以使用中等強度的密碼,例如 12-14 個隨機字母和數字(雖然沒有字典單詞!),然後將其與其他一些參數(例如鹽、迭代次數和所需的密鑰長度)一起放入 PBKDF 函式中。
之後,你就有了一個相當強大的——比如 128 位密鑰——用於真正的 AES 加密/解密。
有關詳細資訊,請參閱http://en.wikipedia.org/wiki/PBKDF2
還有一件事。為了防止暴力破解您的密鑰,您應該試驗密鑰派生的迭代次數。作為一個好的經驗法則,選擇一個使算法在目標機器上執行大約 1 秒的數字。
您正在尋找的是一個偽隨機函式,即使傳遞給它的關鍵材料不是,它也應該與製服無法區分。您的方案的一個潛在問題是 AES 密鑰調度不是特別擅長從未隨機選擇(偽)的密鑰(例如密碼和密碼片語)中提取熵。例如,針對 AES-256 的相關密鑰攻擊證明了這一點。在使用 AES-ECB 對密碼進行“散列”之前,您可以使用 CBC-MAC 和常量密鑰作為密鑰提取器來解決此問題。(類似的技術例如在 FIPS 180-4 中用於濃縮由熵源生成的熵。)即:
讓 $ K_0 $ 是一個固定的常數鍵。
為了散列密碼 $ P $ (以八位字節字元串的形式)帶有 128 位(唯一)鹽 $ S $ , 請執行下列操作:
- 軟墊 $ P $ 單個八位組 0x80 後跟零到 15 個八位組,其值為 0x00,形成一個八位組字元串 $ P’ $ 長度為 16 的倍數。
- 劃分 $ P’ $ 進入 $ k $ 塊 $ p_1…p_k $ 八位字節長度為 16. 讓 $ c_0 $ 是一個零值塊並且 $ p_{k+1} = S $ .
- 為了 $ i $ 從 1 到 $ k+1 $ , 讓 $ c_i = AES_{K_0}(c_{i-1} \oplus p_i) $
- 讓 $ K = c_{k+1} $ .
- 讓 $ h_0 $ 是一個零值塊。
- 為了 $ i $ 從 1 到 $ iter $ , 讓 $ h_i = AES_{K}(h_{i-1}) $
- 輸出 $ h_{iter} $ .
請注意,上述算法引入了您的問題中未提及的三個功能:首先,它支持任意長度的密碼和密碼片語。其次,它引入了一種鹽,用於防止攻擊者建構常用密碼字典。第三,它引入了一個 $ iter $ 增加蠻力測試(特別是)低熵密碼所需努力的參數。