Encryption

這個文件加密方案的正確/錯誤密碼是否安全?

  • January 25, 2020

我正在編寫一個 AES 文件加密程序,我想在不解密整個文件的情況下判斷使用者是否輸入了正確的密碼,並且 GCM 告訴我標籤無效。

我的流程如下:

  • 讓使用者輸入密碼( $ p $ ),生成鹽/隨機數/IV ( $ n $ ),並用於Scrypt生成 2 個密鑰(生成密鑰的前半部分和後半部分);$$ k_1, k_2 = Scrypt(salt:n, keylen:32, n:2^{16}, r:8, p:1).derive(p) $$
  • 使用加密文件的數據 $ \text{AES-GCM-128(}k_1, \text{iv/nonce=n}) $ 並清空相關數據。
  • 將加密數據寫入文件,使文件內容為 $ n || gcmtag || data $

如果我將以下內容寫入文件是否安全: $$ n || gcmtag || k_2 || data $$

這意味著我可以載入 $ n $ 從文件中獲取使用者輸入的密碼,導出密鑰,並檢查 $ k_2 $ 相當於 $ k_2 $ 從文件中載入。

您的 $ k_2 $ value 的執行方式與傳統密碼驗證方法相同,您可以在其中儲存使用者密碼的加鹽密碼雜湊。所以它允許對手測試密碼猜測,但是——

  1. 經過身份驗證的 GCM 也是如此 $ (c, tag) $ 一對;
  2. 無論如何,memory hard scrypt 功能是您抵禦這種攻擊的主要防線。

非常強烈地考慮的替代方案:不是在一次 GCM 加密呼叫中加密整個文件,而是將其分成塊以單獨加密,並使用一些防止重新排序、刪除和截斷的結構。研究這些例子:

這樣做的主要原因是,您可以加密/解密具有固定記憶體佔用的非常大的文件,但一旦遇到不真實的塊,就會中止解密。其次,它還間接解決了您的問題:如果使用者輸入了錯誤的密碼,那麼解密將在第一個塊上失敗。

潛在的缺點是:

  • 加密會以純文字大小的一定百分比生成更大的文件(而不僅僅是像您的建議那樣的固定成本);
  • 如果加密文件在第一個塊之後被摻假,您可能會在中止之前輸出明文的前綴,這在某些應用程序中可能是一個問題(或不是)。

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