PBKDF2 和鹽
我想問一些關於PBKDF2函式的問題,以及一般關於基於密碼的派生函式的問題。
實際上,我們將派生函式與鹽一起使用來抵抗字典攻擊,對吧?一個例子是 UNIX 加密方案。
我的第一個問題:
例如,如果要加密卡中的一條數據,並且我使用密碼通過 PBKDF2 函式派生新密鑰,通常鹽是未加密儲存的,對嗎?但是,如果攻擊者可以訪問卡並找到鹽,那麼我們唯一的安全措施就是再次輸入密碼,不是嗎?那麼,為什麼我們要把鹽存放在透明的地方呢?我知道這使字典攻擊變得更加困難,但是如果有人可以訪問該卡,那麼我們首先要注意的是密碼的長度,對嗎?
此外,我們有相同的場景:
我們有密碼,我們想生成一個新密鑰,我們使用 PBKDF2 或任何其他函式(我知道它有 HMAC 作為生成器)。直到現在,我還沒有找到任何地方解釋函式的結果,實際的密鑰是否被儲存?另外,給定密碼,我們如何知道密碼是否正確,以便推導出實際密鑰?
首先,認識到 PBKDF2 是 PKCS #5 是 RFC 2898,即http://www.ietf.org/rfc/rfc2898.txt
它本質上是一種算法,可以根據需要多次安全地對密碼進行雜湊處理,無論您想要什麼雜湊值。根據https://www.owasp.org/index.php/Password_Storage_Cheat_Sheet,OWASP建議在 2012 年至少對密碼進行 64,000 次雜湊處理,並每兩年翻一番
請注意,儲存(也以明文形式)每個使用者的可變迭代次數也有幫助。與其總是執行 PBKDF2 64,000 次,不如生成一個隨機鹽和一個介於 1 到 20,000 之間的隨機數 I。為該特定使用者名執行 PBKDF2 64,000 + I 次。這使得破解它變得更加困難,並且可能會阻止破解程式碼中的某些優化有用。
實際上,我們使用派生函式和鹽來抵抗字典攻擊,對吧?
本質上 - 我們在散列之前對明文密碼進行加鹽。
我的第一個問題:…通常鹽儲存未加密,對嗎?
在更簡單的實現中,一個長的(8 字節或更多)加密隨機鹽未加密儲存,並在每次密碼更改時重新生成。OWASP(上面的連結)建議採取額外的預防措施,包括將額外的鹽儲存在某個配置文件中(即不儲存在數據庫中),將另一部分硬編碼在原始碼中,並將每個使用者的鹽儲存在與密碼不同的位置,也許是平面文件與數據庫(反之亦然)。請注意,理想情況下,這還需要將密碼和鹽備份到不同的位置 - 目標是使一次盜竊同時竊取鹽和密碼變得更加困難。
此外,我們有相同的場景:我們有密碼並且我們想要生成一個新密鑰……直到現在,我還沒有找到任何解釋函式結果(實際密鑰(它是否被儲存?
那要看。如果您僅在此會話期間使用 PBKDF2 生成用於實時加密的密鑰,那麼不,它應該只保留在記憶體中,並在最後被丟棄。如果您使用 PBKDF2 生成雜湊(經過 N 次迭代)以稍後對使用者進行身份驗證,那麼您必須保存該雜湊。
我知道這會使字典攻擊更難,但是如果有人可以訪問我儲存的卡,那麼我們是第一個,唯一的預防措施是密碼的長度正確
不,唯一的預防措施是力量的密碼。“P@ssw0rdP@ssw0rdP@ssw0rd”是一個錯誤密碼,即使它是 24 個字元長且“複雜”。如果您要“註冊”使用者,或者讓他們選擇密碼,您需要拒絕最常見的破解字典中的任何密碼。此外,當您測試拒絕時,您需要應用與基於規則的字典破解器(如 Elcomsoft 或 Hashcat)使用的相同類型的規則 - 轉換為 1337 說話,在其後添加 1 到 1000,在前後添加隨機字元, double it, etc. 謝天謝地,這在前端更容易,因為您可以簡單地反向翻譯 1337 說話並將其小寫,因此 P@ssw0rd 和 Passw0rd 都以“密碼”結尾,應該被過濾掉。Melinda2006 總是一個錯誤的密碼,12345 也是如此。
此外,給定密碼,我們如何知道密碼是否是正確的密碼以導出實際密鑰?
你事先不知道;你試試看。如果有效,那就對了。如果它不起作用,那就錯了。現在,再次通過“作品”,這取決於。對於實時解密,您將嘗試解密消息;然後,您將保存的 HMAC 與消息(加密之前)與值進行比較;如果 HMAC 不匹配,則為偽造,部分消息被更改,您有錯誤,或密碼錯誤。對於身份驗證,您收集本應使用的鹽值,然後以相同的次數重新散列密碼。如果你得到相同的散列結果,那麼輸入一定是相同的,所以它是正確的。
基於密碼的密鑰派生函式從給定的密碼生成適合密碼的密鑰。它只依賴於原始密碼被保密。
鹽的目的只是為了防止使用彩虹表。必須為每種鹽製作彩虹表,如果(按照慣例)每個使用者都有自己的鹽,則必須為該特定使用者建構彩虹表。一般來說,它不被認為是秘密的。
鹽與 PBKDF 函式內的更多迭代一起使用,以阻止任何創建彩虹表的嘗試。
從 PBKDF2 派生的密鑰儲存在某處
我想您可能已經混淆了儲存用於身份驗證的密碼的加密雜湊和 PBKDF(可以使用底層加密雜湊)來“拉伸密碼”以用於加密。
生成的密鑰不應儲存在任何地方(除非其本身經過適當加密)。生成的密鑰用於加密。當要解密數據時,應提示使用者輸入密碼,並再次生成密鑰。然後使用這個生成的密鑰來解密數據。
我們如何知道我們提供的密碼是正確的,以便執行 PBKDF2 功能?
加密數據時,您還應該包括消息身份驗證 (MAC)。這通常意味著加密
message || MAC
。您將使用(可能是錯誤的)密鑰解密數據。然後檢查MAC和消息是否對應。如果他們不這樣做,要麼密鑰是假的,要麼密文已被篡改。或者,您可以散列密碼。儘管可以為此使用 PBKDF,但應該清楚必須使用不同的鹽(即使您不使用相同的算法)。儲存此雜湊。當使用者輸入他們的密碼時,您對其進行雜湊處理,並使用儲存的雜湊進行檢查,如果它們匹配,您將繼續生成加密密鑰並解密數據。