密碼存明文,誰(shuí)看了都搖頭,你的系統(tǒng)中是怎么存密碼的?
密碼是一個(gè) IT 系統(tǒng)中很敏感、很重要的部分,尤其是早期的系統(tǒng),往往登錄一個(gè)系統(tǒng)只要一個(gè)賬號(hào)和密碼就可以了。
很多賬號(hào)被盜都是因?yàn)槊艽a泄露了,密碼泄露有很多種可能,比如暴力破解、社工破解。
還有一種就是所謂的拖庫(kù),也就是數(shù)據(jù)庫(kù)數(shù)據(jù)被攻擊者導(dǎo)出了。這樣一來(lái),如果系統(tǒng)中的密碼存儲(chǔ)過(guò)于簡(jiǎn)單,很容易會(huì)被破解。而一個(gè)系統(tǒng)的密碼被拿到后,往往會(huì)被攻擊者用來(lái)嘗試登錄其他的系統(tǒng),因?yàn)楹芏嗳擞猛粋€(gè)密碼在互聯(lián)網(wǎng)上沖浪。
早些年就有一些網(wǎng)站被拖庫(kù),而數(shù)據(jù)庫(kù)中的密碼字段竟然是用明文存儲(chǔ),導(dǎo)致大量用戶的密碼被泄漏。
圖片
那密碼如此重要,如何存儲(chǔ)才能保證密碼足夠安全呢,即使被拖庫(kù)也能保證密碼不被破解呢?
明文密碼打死不能存
首先,明文密碼是無(wú)論如何都不能入庫(kù)的,可能只是互聯(lián)網(wǎng)早期有這樣存的。稍微有點(diǎn)經(jīng)驗(yàn)的開(kāi)發(fā)者也一定清楚,肯定不能存明文密碼。
但凡有個(gè)安全評(píng)測(cè),明文密碼這件事也不可能發(fā)生。
哈希值和弱哈希加密盡量不用
比明文密碼好一點(diǎn)的是存密碼的哈希值,或者一些很簡(jiǎn)單的加密算法,比如MD5、SHA-1。
我記得很早之前自己做系統(tǒng)的時(shí)候,不知道從哪兒看來(lái)的方法,就是把密碼直接用 MD5 加密存儲(chǔ)的,因?yàn)?MD5 是不可逆的,也就是不能從MD5加密后的結(jié)果轉(zhuǎn)換回加密之前的結(jié)果,所以當(dāng)時(shí)就想當(dāng)然的認(rèn)為這是安全的。
后來(lái),聽(tīng)說(shuō) MD5 雖然不可逆,但是破解起來(lái)也是相對(duì)容易的,比如碰撞攻擊和彩虹表攻擊,都有可能將 MD5 解密。
而且有很多在線工具提供解密 MD5 的功能。之前接手過(guò)一個(gè)項(xiàng)目,密碼就是用 MD5 加密的,然后我隨便找一個(gè)密碼用一個(gè)在線工具,很快就能解密出來(lái),可見(jiàn)一點(diǎn)兒也不安全。
圖片
所以,這種弱加密方式也盡量不要用。
密碼加鹽才是正解
加鹽(Salt)是指在密碼哈希之前,向密碼中添加一個(gè)隨機(jī)生成的字符串。鹽值是唯一的,甚至對(duì)于相同的密碼,每次生成的哈希值也會(huì)不同。
圖片
如上圖所示,將一個(gè)隨機(jī)的鹽(salt)和密碼進(jìn)行哈希運(yùn)算 hash(password+salt),將算出來(lái)的結(jié)果存到表中,另外將 salt 值也一并存入。
在進(jìn)行密碼驗(yàn)證的時(shí)候,取出當(dāng)前用戶的 salt 和 用戶輸入的密碼,通過(guò)同樣的方式運(yùn)算hash(password+salt),最后將運(yùn)算結(jié)果和已存儲(chǔ)的hash值進(jìn)行比對(duì),如果一致說(shuō)明密碼正確。
圖片
這樣一來(lái),即使有人拿到了數(shù)據(jù)庫(kù)中存的 salt 和 hash 也不能獲取原始密碼。什么暴力破解、彩虹表攻擊這些手段,在加入了 salt 的情況下,都會(huì)變得非常復(fù)雜,幾乎是無(wú)法破解的。
如果更嚴(yán)謹(jǐn)一點(diǎn)兒,可以搞兩個(gè)salthash(password + salt + otherSalt),這樣安全性會(huì)更高一些。
其中 salt 有兩點(diǎn)需要注意一下:
- 不能太短,最好長(zhǎng)一些,破解難度很大很多;
- 不能全局用同一個(gè) salt,每一個(gè)密碼要有一個(gè)隨機(jī)的salt;
不用密碼更安全
存密碼就有風(fēng)險(xiǎn),現(xiàn)在很多系統(tǒng)都不支持使用賬號(hào)密碼方式登錄,而是用更加安全的方式。
比如多因素認(rèn)證(MFA),比如 GitHub 就強(qiáng)制要求使用這種方式,阿里云也提供這種方式。
再比如短信驗(yàn)證碼登錄,或者使用其他具有公信力的第三方服務(wù)登錄,比如微信登錄、支付寶登錄等。
這些方式?jīng)]有賬號(hào)密碼,比如短信登錄,只有知道手機(jī)號(hào),并且能夠拿到手機(jī)驗(yàn)證碼才行。即使有人知道了你的賬號(hào),但是想拿到你的手機(jī)還是很麻煩的吧。