php登錄加密加鹽
1 背景
涉及身份驗證的系統都需要存儲用戶的認證信息,常用的用戶認證方式主要為用戶名和密碼的方式,為了安全起見,用戶輸入的密碼需要保存為密文形式,可采用已公開的不可逆的hash加密算法,比如SHA256, SHA512, SHA3等,對於同一密碼,同一加密算法會產生相同的hash值,這樣,當用戶進行身份驗證時,也可對用戶輸入的明文密碼應用相同的hash加密算法,得出一個hash值,然後使用該hash值和之前存儲好的密文值進行對照,如果兩個值相同,則密碼認證成功,否則密碼認證失敗。
由於密碼是由用戶設定的,在實際應用中,用戶設置的密碼復雜度可能不夠高,同時不同的用戶極有可能會使用相同的密碼,那麽這些用戶對應的密文也會相同,這樣,當存儲用戶密碼的數據庫泄露後,攻擊者會很容易便能找到相同密碼的用戶,從而也降低了破解密碼的難度,因此,在對用戶密碼進行加密時,需要考慮對密碼進行掩飾,即使是相同的密碼,也應該要保存為不同的密文,即使用戶輸入的是弱密碼,也需要考慮進行增強,從而增加密碼被攻破的難度,而使用帶鹽的加密hash值便能滿足該需求。
2 加密鹽的實現方法
2.1 加密存儲
輸入: 密碼字符串passWord
輸出:鹽值 salt 、密碼密文passWordHash
函數:加密hash函數
其中:“鹽值 salt”是在加密過程中生成的隨機字符串;
可以將salt放到passWord前面作為前綴或放到passWord後面作為後綴得到新的字符串PS,即,PS = password和salt的組合串;
密碼密文passWordHash = Hash加密函數(PS );
將用戶名、密碼密文passWordHash和鹽值salt一起保存到數據庫中。
2.2 密碼校驗
輸入: 密碼字符串passWordCur
輸出:密碼校驗是否成功
處理: 1)、取出當前用戶密碼加密時使用的鹽值salt
2)、得到本次輸入的密碼passWordCur和鹽值salt的組合字符串PS
3)、得出本次輸入密碼的密文passWordHashCur= Hash加密函數(PS );
4)、比較passWordHashCur和用戶最初設置的密碼密文passWordHash是否一致,如果一致,則校驗成功,否則校驗失敗。
3 常用的密碼攻擊方式
常用的密碼攻擊方式有字典攻擊、暴力破解、查表法、反向查表法、彩虹表等。
對字典攻擊和暴力破解,攻擊者均采用逐密碼嘗試的方式,目前沒有很好的手段來阻止字典攻擊和暴力破解攻擊,只能是想辦法讓這兩種攻擊方式變得相對低效一些,而相同的密碼產生不同的hash值便能讓攻擊者針對每一個hash值都需要從頭進行嘗試,從而使攻擊變得更加低效。
對查表法、反向查表法和彩虹表攻擊方式,攻擊者需要提前準備好包含密碼和密碼hash值的密碼表,然後根據該表和用戶密碼數據庫進行批量匹配,從而達到攻破密碼的目的;而如果我們在加密時,給每個密碼附加了不同的隨機值,這樣每個密碼對應的hash值也會不同,這樣攻擊者在準備密碼表時,就必須要將最基本的密碼和用戶密碼數據庫中的鹽值進行笛卡爾積後再計算hash值,鹽值越多,用戶需要準備的表量越大,這樣對於攻擊而言,就變得有些得不償失了。
4 加鹽的註意事項
加鹽的目的是為了增加攻擊者破解的難度,那麽在加鹽的時候要註意以下幾點,否則加鹽的意義也不會太大。
1)、鹽值不能太短;如果鹽值只有少數兩三位甚至一兩位的話,攻擊者完全可以窮舉所有可能的鹽值;關於鹽值長度的一個經驗值是長度至少要和hash加密函數的返回值長度保持一致。
2)、鹽值不能固定;如果系統使用了固定的鹽值,那麽和不加鹽相當於是一回事了,攻擊者完全可以使用該固定的鹽值提前準備密碼表;另外,相同密碼對應的hash值仍然是一樣的,仍然無法對密碼相同這一事實進行掩飾。
3)、不要使用能提前預知的值作為鹽值;如果鹽值能提前得知或提前推斷出,攻擊者也完全可以根據提前預知的鹽值準備密碼表,從而對破解的難度也增加不了多少。
4)、每一次修改密碼重新計算hash值時,要重新生成新的鹽值,不要使用上次密碼對應的鹽值;因為如果用戶密碼泄露之後,鹽值相應的也就泄露了,用戶修改密碼時,如果還沿用原來的鹽值,攻擊者也仍然可以根據上次的鹽值提前準備密碼表,從而使攻破可能性變得更高了。
php登錄加密加鹽