資料庫到底應該如何儲存密碼?
最近接手公司一個之前的服務,竟然發現使用者密碼是明文儲存在資料庫中!
說實話還是有點吃驚的,至少也得搞個 MD5 存一存吧。
不過 MD5 其實也沒啥用,今天我們就來盤盤密碼這種敏感資訊該如何儲存。
資料庫為什麼不能明文儲存密碼
不僅僅是為了防止系統管理員或者DBA等公司人員獲得使用者的密碼,也是防止被駭客拖庫產生更大的資訊洩露。
如果駭客透過不法手段獲取了服務的資料庫儲存資訊,盜取裡面的內容,從而直接獲得明文密碼,那麼影響就會很大。
因為絕大部分人所有賬戶的密碼都會設定成一樣的,只要知道一個網站的明文密碼後,基本上等於搞定這個使用者其他網站的所有賬號,也就是撞庫。
所以不能明文儲存密碼,需要加密下。
MD5 不是加密演算法
實際上,經常有人會說拿 MD5 加密,這樣說沒問題,但是我們心裡要清楚 MD5 壓根就不是加密演算法,它其實就是個摘要演算法。
加密演算法指的是把一段資料加密後,可以解密。
很明顯 MD5 無法解密,只能暴力窮舉破解,所以它不算是加密演算法。
為什麼用 MD5 儲存密碼不好
大部分人的密碼都會設定得比較簡單,比如名字縮寫加個出生日期這種。
而駭客其實會針對常見的一些密碼,生成彩虹表。
彩虹表:是用於加密雜湊函式逆運算的預先計算好的表,常用於破解加密過的密碼雜湊(維基百科)
就像下面的表格:
這樣一來只要準備得足夠充分,彩虹表足夠大,那麼直接對比彩虹表就能反推得出明文密碼,所以直接簡單用 MD5 也是不安全。
給密碼加點鹽
那咋辦麼?
其實彩虹表大部分能找到的只是常見的密碼。
基於這點,我們雖然不能強迫使用者設定一些非常複雜的密碼(這記憶成本太高)。
但是我們可以手動給使用者的密碼拼接上一些複雜的字元,然後經過雜湊函式處理之後落庫。
比如使用者初始密碼是123456,我們可以給他的密碼加點鹽,鹽其實就是一些複雜的字元數字,比如:
這樣即使不法分子盜取到密碼,預先準備的彩虹表(因為密碼變得不常見了)也無用,使得破解的成本變高。
這種鹽叫固態鹽,不需要落庫儲存,一般在程式碼或者配置中儲存。一旦被不法分子試出這個的鹽,那麼繼而就能透過這個鹽試出別的密碼。
所以推薦動態鹽,即讓每個賬號下密碼加的鹽都是不一樣的,這樣一來不法分子的破解成本就更高了。
動態鹽需要分別為每個使用者記錄對應密碼加的鹽值,一般是落庫儲存,比如上圖所示在使用者表上加個 salt 欄位。
又或者直接跟密碼拼一起中間用特殊符號切分等等,比如下圖用 $ 來分割。(沒錯動態鹽是直接儲存的,也就是說攻擊者可以拿到每個賬號的鹽)。
我還看過一些方案,比如不加欄位也不用分隔符,把使用者的建立時間進行處理作為動態鹽,等等。
加鹽這種手段僅僅只是增加了攻擊者的破解成本,因為攻擊者知道鹽值,從而就能反推出一個值,使得這個md5(值+鹽) = md5(密碼+鹽)
。
因為不論這個值是否等於密碼,反正只要最終 hash 的結果是一樣的,就都能登入,所以攻擊者要推是可以推出來的,只不過成本會高些。
總而言之,透過摘要演算法來儲存密碼,不法分子是可以透過暴力、彩虹表、字典等方式來破解。
如果你僅僅是用 md5 處理密碼儲存,那麼這些破解其實成本也不是很大,咋一說你可能沒啥感覺,我在網上看到一個結論:md5 來儲存 6 位長度的密碼(僅僅包含小寫和數字),只需要 40 秒,就可以窮舉所有密碼。
bcrypt
因此,為了進一步給駭客們增加破解成本,需要替換 md5 這類 hash 快速的方法,換成 bcrypt 這種演算法。
md5 計算只需要 1 微妙,而 bcrypt 需要 0.3 秒,速度差了 30 萬倍。
1秒=1000000 微秒
因此,如果本來 40 秒就能破解的話,換成 bcrypt 後變成 138 天才能破解!
bcrypt 就是這麼個雜湊演算法,它有個迭代次數,可以使得計算變慢,非常適合這種場景!
不用摘要演算法,加密儲存行嗎?
其實還有一種防破解的方式,就是採用加密演算法。
比如採用對稱加密 AES,這樣只要金鑰不洩露,攻擊者拖庫拿到密碼也完全破解不了!
但是反過來想,假設金鑰被洩漏了,那就是白給,比破解上述的hash(密碼+鹽)更輕鬆,連試試都不需要。
所以加密儲存的話就得看你的金鑰保不保得住了。
最後
大致方案就這麼幾種。動態鹽其實已經 OK 了,不過演算法儘量別用 md5,可以用 sha1、sha256 這些,因為 md5 其實已經被破解了。
這裡的破解不是說透過 md5 可以反向推出明文,而是利用 md5 hash 後的值能快速的找到另一個值使得 md5 的結果一致。
好了,今天這篇就說這麼多了,更多的可以自行上網查閱。
md5 和 bcrypt 的速度對比來源下面這篇文章:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70024420/viewspace-2925887/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 資料庫儲存時間到底該用什麼型別?資料庫型別
- 面對海量的監控影片資料應該如何儲存?
- 如何安全的儲存密碼密碼
- 資料庫連線池到底應該設多大?資料庫
- 如何安全地儲存密碼?密碼
- 大資料到底應該如何學?大資料
- 安全密碼儲存,該怎麼做,不該怎麼做?密碼
- 儲存使用者密碼應該使用什麼加密演算法?密碼加密演算法
- 什麼時候該使用NoSQL儲存資料庫?SQL資料庫
- 忘記oracle的sys密碼該如何重置;附如何修改oracle資料庫使用者密碼Oracle密碼資料庫
- 列式儲存資料庫資料庫
- Flutter持久化儲存之資料庫儲存Flutter持久化資料庫
- 網頁密碼儲存網頁密碼
- 區塊鏈Yottachain到底是如何改變資料儲存模式?區塊鏈AI模式
- 如何在安卓應用程式中儲存資料安卓
- 【資料庫】資料庫儲存過程(一)資料庫儲存過程
- win10 mstsc怎麼儲存遠端密碼_win10 mstsc如何儲存遠端密碼Win10密碼
- MySQL 資料庫儲存引擎MySql資料庫儲存引擎
- 資料庫儲存過程資料庫儲存過程
- sql server資料庫如何儲存陣列,int[]float[]double[]陣列儲存到資料庫方法SQLServer資料庫陣列
- 如何在資料庫中儲存一棵樹資料庫
- IOS資料儲存之Sqlite資料庫iOSSQLite資料庫
- IOS資料儲存之FMDB資料庫iOS資料庫
- 清除SVN儲存的密碼密碼
- sqlserver資料庫還原儲存過程指令碼SQLServer資料庫儲存過程指令碼
- 使用儲存指令碼還原恢復資料庫指令碼資料庫
- 你應該知道的前端--儲存前端
- win10檢視儲存的wifi密碼_如何檢視win10電腦儲存的wifi密碼Win10WiFi密碼
- 如何加密傳輸和儲存使用者密碼加密密碼
- 報表資料分庫儲存
- MySql資料庫——儲存過程MySql資料庫儲存過程
- MySQL資料庫操作、儲存引擎MySql資料庫儲存引擎
- gitlab資料庫儲存位置Gitlab資料庫
- 使用Room持久庫儲存資料OOM
- 管理資料庫儲存結構資料庫
- 儲存與資料庫系統資料庫
- 明解資料庫------資料庫儲存演變史資料庫
- 【資料庫】資料庫儲存元素型別基礎資料庫型別