數據庫行級加密方案
我想保護數據庫中一些高度敏感的數據。這意味著如果數據落入對手手中,則需要對其進行加密並在 100 年內保持安全。我還想限制 RAM 中一次易受明文攻擊的數據量。這樣就不太可能將明文數據分頁到磁碟。此外,數據庫可能非常大,因此它需要比一次解密整個數據庫來訪問它更有效。因此,我正在考慮在數據庫行級別加密敏感數據。這意味著引用記錄的唯一索引是未加密的,因此仍然可以找到/檢索每條記錄,但是敏感數據本身是加密的。
我的解決方案是讓每個數據庫行的數據:
index | IV | sensitive encrypted data | MAC
- 256 位數據庫密鑰將用於加密將使用 /dev/random 生成的敏感數據。
- 每行的 IV 將是來自 /dev/urandom 的 256 位(比 /dev/random 快)。
- 加密算法將是 Twofish。
- 每條記錄的 MAC 將是使用密鑰的索引、IV 和敏感數據的 HMAC-SHA3。
該系統是單使用者的。使用者將創建一個強字母數字密碼(最少 14 個字元)。
基於密碼的密鑰派生函式將在密碼片語上執行以創建派生的加密密鑰,然後將使用該密鑰分別使用 Twofish 加密數據庫密鑰。這樣使用者就可以更改他們的密碼,而不必重新加密整個數據庫——他們只需創建一個新密碼並重新加密數據庫密鑰即可。
- 為了從密碼中獲取密鑰,PBKDF2 將使用 HMAC-SHA3 進行 10,000 次迭代,輸出為 256 位,並從 /dev/urandom 獲得 256 位的鹽。
- 我要做的是平衡使數據安全所需的密碼字元數量與為處理器速度慢且記憶體有限的移動設備上的使用者提供合理快速的密碼字元數。我不希望使用者等待 PBKDF 完成超過 5 秒。
- MAC 是使用 HMAC-SHA3-256(派生加密密鑰,鹽 | 加密數據庫密鑰)創建的,並儲存在磁碟上的鹽和加密數據庫密鑰旁邊。這可以在登錄時進行驗證,以確保他們輸入了正確的密碼。
當程序載入時,使用者輸入密碼。KDF 執行,生成用於解密數據庫加密密鑰的密鑰。真正的加密密鑰是程序執行時唯一保存在 RAM 中的東西,並在需要時用於驗證和解密各個數據庫記錄。
- 行級別 IV 的最佳長度是多少?256位好嗎?
- PBKDF2 的 14 個字元和 10,000 次迭代的最小密碼強度是否足以保護 256 位數據庫密鑰?如果不是,哪些參數會起作用?
- PBKDF2 仍然是一個很好的算法嗎?如果不是,Scrypt 參數是什麼?
- 是否有任何進一步的更改或建議以確保系統安全?
迭代的工作方式是通過以下方式大致提高您的安全性(以位為單位) $ \log_2(iterations) $ . 所以你仍然需要 $ \frac{\log{2}}{\log{97}}\cdot (256 - \log_2(10000)) \approx 37 $ 密碼中的字元具有 256 位安全性。這樣想,如果你有 $ 2^{256} $ 可能的密鑰,這是一個天文數字。遠遠超過宇宙中基本粒子的數量。相比之下,一萬基本不算什麼。增加密鑰空間可以為您提供指數安全性,而向密鑰派生函式添加迭代只能為您提供線性安全性。這很好,但歸根結底,它並沒有你想像的那麼有用。
話雖如此,您可能仍然不需要 256 位的安全性。正如我之前所說,這是一個荒謬的安全性。計算能力的提高不會讓任何人暴力破解 256 位密鑰。計算存在物理限制,需要十幾個恆星的全部能量才能做到這一點。我們擁有 AES-256 之類的東西的原因是,我們預計未來人們會發現針對 AES 的更有效的攻擊,這些攻擊不需要暴力破解。但是,我們希望通過更長的密鑰延遲這些攻擊。因此,如果有人發現及時有效的攻擊 $ 2^{n/2} $ , AES-128 將被有效破解。但是,使用 AES-256,我們仍然擁有 128 位的安全性,這應該足夠長一段時間了。
100 年來,您真正需要的安全位數接近 120-150。今天任何人都可以暴力破解的外部限制可能是 70-80 位,記住添加位會給您帶來成倍增加的安全性。因此,您實際上只需要一個 17-20 個字元長的密碼。