最近數(shù)據(jù)庫泄漏事件層出不窮,無數(shù)人的上網(wǎng)密碼被人破解。本文來探討一下如何安全地保存用戶的密碼。
為什么非要安全地保存密碼?因?yàn)槿祟愂褂妹艽a有三大偏好:
喜歡用簡單好記的密碼
喜歡到處用相同的密碼
不喜歡經(jīng)常地修改密碼
為了你的客戶不至于因?yàn)槟愕臄?shù)據(jù)庫泄漏事故和損失慘重,請(qǐng)保護(hù)好他們的密碼!
最爛的方式:明文保存
許多早期制作的網(wǎng)站,還有眾多的政府網(wǎng)站,都是這么保存密碼的,包括著名的CSDN也是。有的時(shí)候這么保存密碼是不得已的:我曾經(jīng)接到過一個(gè)政府部門的項(xiàng)目,領(lǐng)導(dǎo)要求在他忘記密碼的時(shí)候能讓單位負(fù)責(zé)IT工作的小王幫助查一下密碼是什么。不過還好一般并不難說服領(lǐng)導(dǎo)換另一種方式:如果您忘了密碼,可以用手機(jī)重設(shè)密碼。
明文保存密碼的方法把密碼安全完全交給了運(yùn)維。任何安全漏洞,不論是操作系統(tǒng)漏洞,還是數(shù)據(jù)庫漏洞,甚至應(yīng)用程序中的漏洞,都會(huì)導(dǎo)致用戶的密碼大白于天下。
次爛的方式:MD5保存
相對(duì)明文密碼好一點(diǎn)的方法是把用戶的密碼直接哈希保存。可惜大多數(shù)用這種方式保存密碼的人并不是因?yàn)橐庾R(shí)到明文保存密碼有什么不妥,僅僅是因?yàn)閷W(xué)習(xí)編程的時(shí)候教材上是這么做的。利用單向哈希算法保存密碼當(dāng)然能比明文保存好一點(diǎn)點(diǎn),但其最大的問題卻在于會(huì)讓開發(fā)者誤以為用戶的密碼是非常安全的——即使泄漏了數(shù)據(jù)庫,黑客也不可能知曉用戶的密碼是什么。
且不說MD5已經(jīng)被證明是非常不安全的哈希算法,即使換成SHA-1或者復(fù)雜度更高的哈希算法,也不可能顯著地提升用戶密碼的安全性,因?yàn)楹诳凸舻姆绞酵⒉皇峭ㄟ^數(shù)學(xué)方法尋找哈希碰撞,而是直接在字典中查詢。每個(gè)黑客手上都有上千萬條記錄的密碼字典,包括常用的單詞、拼音、19xx到20xx年的生日等等。他們只需要把MD5的結(jié)果輸入,就能在字典庫中找到對(duì)應(yīng)的原文。一般一個(gè)MD5的密碼庫泄漏的時(shí)候,超過八成密碼能在字典中反查得到。
比較好的方式:加鹽哈希保存
如果定義一個(gè)長字符串,把它插入到用戶密碼中的某個(gè)地方,然后再哈希出結(jié)果,這樣可以改變用戶密碼的哈希結(jié)果,使字典攻擊失效。
比如用戶的密碼是abc123
,直接MD5的結(jié)果是e99a18c428cb38d5f260853678922e03
,大多數(shù)黑客的字典中都有這條記錄。如果我們把用戶的密碼加上這個(gè)前綴ask3Kxsk777sA00bdsOo552
,變成ask3Kxsk777sA00bdsOo552abc123
,然后再進(jìn)行MD5計(jì)算,得到的就是3ee795c4ceadf8b21a12f6e373cb1c56
,一般黑客的字典里都不會(huì)有這條記錄。這里用到的前綴就被稱作“鹽”
加鹽哈希保存的結(jié)果是,黑客需要同時(shí)取得你的數(shù)據(jù)庫和你的“鹽”,并且加鹽重新生成整個(gè)字典庫才能破解你的用戶密碼。安全性比直接哈希保存要高多了。
更好的方式:隨機(jī)加鹽哈希保存
這是對(duì)于上一種方法的改進(jìn)。在前面的方法中,鹽是固定的,加鹽的位置是固定的,以當(dāng)今的計(jì)算機(jī)速度,黑客只需要多花點(diǎn)心思把你的鹽搞到手,然后再花個(gè)一兩天把密碼庫加鹽跑一遍,還是能破解你大多數(shù)用戶的密碼。
如果在保存密碼的時(shí)候鹽隨機(jī)生成,并插入到原始密碼的隨機(jī)位置,那么數(shù)據(jù)庫里每條密碼記錄的鹽和加鹽位置都不同,黑客如果要破解密碼,就需要為每一個(gè)密碼生成一遍字典庫,工作量要大得太多了。
最好的方法:沒有密碼
最安全的密碼保存方法就是完全不保存用戶密碼?,F(xiàn)在各大社交網(wǎng)站都支持賬戶接入非常發(fā)達(dá),完全可以讓用戶用微博、微信、QQ、豆瓣、淘寶、人人、Google、Yahoo、Twitter、Facebook等等等等各種第三方賬戶來登錄你的系統(tǒng),再不濟(jì)也可以讓用戶用隨機(jī)短信密碼來登錄。沒有保存密碼,就不會(huì)丟失密碼。