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