使用加密作為身份驗證
我正在建構一個應用程序,我想在其中加密使用者數據並支持離線登錄。
從這個關於使用密碼進行加密的答案中:
最佳實踐是使用 PBKDF 生成“密鑰加密密鑰”(KEK),然後使用全熵隨機密鑰加密數據,然後使用 KEK 加密該密鑰。
在數據中包含一個已知值是否合理,例如“大家好”(或使用者名,如果每個使用者的可變性會有所幫助?),並通過嘗試解密他們的數據並檢查解密的值是否與已知值?
使用您評論中的編號:1 是,2 否。
如果您只需要加密文件,請盡可能使用年齡。
我將在使用libsodium作為密碼庫的背景下回答其餘的問題。您可能有不同的選擇,例如 NaCl 或 ,但任何選擇都應該支持我將描述的高級 API。如果你的圖書館沒有,那是不安全的,你應該選擇一個更好的。
要生成隨機數(隨機數、鹽等),請使用您的庫的安全隨機生成函式。對於 libsodium,這幾乎總是
randombytes_buf
函式。要將密碼轉換為密鑰,請使用庫的密碼散列函式。如果那是 libsodium,您想使用該
crypto_pwhash
函式對其進行雜湊處理。它接受通過 生成的隨機鹽randombytes_buf
、一些參數限制和密碼,並輸出一個密鑰。您需要將參數和鹽與加密數據一起儲存。使用密碼派生密鑰作為 KEK 而不是直接使用它的原因是允許使用者更改密碼而無需重新加密所有數據。您只需要重新加密實際的數據密鑰。使用的加密方法應該是您圖書館首選的經過身份驗證的加密功能。對於 libsodium,那是
crypto_secretbox_easy
(並且解密是crypto_secretbox_open_easy
)。如果您實際上不需要此功能,請不要包含它,只需使用 PBKDF 的輸出密鑰對數據進行加密即可。您無需檢查數據是否已成功解密。這由 AEAD(帶有關聯數據的身份驗證加密)模式的身份驗證部分處理。如果身份驗證標籤驗證,它會正確解密。如果它沒有驗證,它會丟棄(可能非常危險的)解密數據而不做任何其他事情。
假設您必須使用 libsodium 或類似工具並使用 KEK 系統,您將需要一個隨機鹽、一個用於 AEAD 使用密碼派生的 KEK 加密/解密數據密鑰的唯一隨機數,以及第二個用於加密的唯一隨機數/解密數據。