1 密碼哈希
哈希算法任何數量的數據轉換為無法反轉的固定長度的“指紋”。即使原始輸入的數據變化很小,但是其輸出的結果相差很大。
Hash(“hello”)= 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b98
Hash(“hallo”)= 8756879c05c68dfac9866712fad6a93f8146f337a69afe7dd238ff3f9e94bc3
使用哈希之后,如何校驗用戶的用戶名密碼呢?
用戶創建一個帳戶時。輸入的密碼被散列並存儲在數據庫中。
當用戶登錄時,對其輸入的密碼散列,對照其實際密碼(從數據庫檢索)。
如果哈希匹配,則授予用戶訪問權限。如果不是,則告訴用戶他們輸入了無效的登錄憑
常用的較為安全的密碼哈希算法:SHA256,SHA512,等。
2 破解密碼
因為哈希算法,相同的輸入時,會有一個相同的輸出值。由此就出現了幾種破解方法:
2.1字典和蠻力攻擊
這是最簡單的密碼猜解方法,對每個值進行哈希,然后與數據庫泄露出的密碼哈希值進行對比,如果相同,代表着密碼被猜解。
字典攻擊:使用的字典一般含單詞,詞組,常用密碼以及其他可能用作密碼的字符串。
蠻力攻擊: 嘗試所有可能的字符組合。
雖然如果密碼長度夠長、復雜度較高,會給破解帶來一些難度,但是沒有辦法完全阻止。
2.2 查找表
查找表的思路是字典中,首先預置好哈希值。然后將實際密碼的哈希值與之搜索對比。這是一種非常有效的方法,可以非常快速地破解許多相同類型的哈希。
2.3 反向查找表
這種攻擊特別有效,因為許多用戶通常使用相同的密碼。所以可以對某個字符進行哈希,然后去數據庫中進行查詢此哈希值映射的用戶名。
例如:
在用戶的哈希列表中搜索哈希(password1)...:匹配[小明,小花,小白]
在用戶的哈希列表中搜索哈希(password2)...:匹配[李明]
3 加鹽值
首先可以通過一個場景了解鹽值的作用:
1、小明要注冊某個網站,注冊時密碼填寫為password=123456。
2、為了保證密碼的復雜度,系統可以使用鹽值。將小明輸入的password和salt一起加密后存儲。即最終存儲的密碼為:PASSWORD=123456+salt
由於密碼是由用戶設定的,在實際應用中,用戶設置的密碼復雜度可能不夠高,同時不同的用戶極有可能會使用相同的密碼,那么這些用戶對應的密文也會相同,這樣,當存儲用戶密碼的數據庫泄露后,攻擊者會很容易便能找到相同密碼的用戶,從而也降低了破解密碼的難度,因此,在對用戶密碼進行加密時,需要考慮對密碼進行掩飾,即使是相同的密碼,也應該要保存為不同的密文,即使用戶輸入的是弱密碼,也需要考慮進行增強,從而增加密碼被攻破的難度,而使用帶鹽的加密hash值便能滿足該需求。
3.1 加密存儲
輸入: 密碼字符串passWord
輸出:鹽值 salt 、密碼密文passWordHash
可以將salt放到passWord前面作為前綴或放到passWord后面作為后綴得到新的字符串PS,即,PS = password和salt的組合串;
密碼密文passWordHash = Hash加密函數(PS );
3.2 密碼校驗
輸入: 密碼字符串passWord
輸出:密碼校驗是否成功
處理:
1)、取出當前用戶密碼加密時使用的鹽值salt
2)、得到本次輸入的密碼passWordCur和鹽值salt的組合字符串PS
3)、得出本次輸入密碼的密文passWordHashCur= Hash加密函數(PS );
4)、比較passWordHashCur和用戶最初設置的密碼密文passWordHash是否一致,如果一致,則校驗成功,否則校驗失敗。
3.4 鹽值的產生與存儲
鹽值應該使用安全隨機數生成;不能寫死在代碼中或者配置文件中、數據庫中。而且對鹽值的長度也應該有一定的要求,較短的鹽值,仍然有被破解的風險。