為什麼要在密碼里加點“鹽”
鹽(Salt)
在密碼學中,是指通過在密碼任意固定位置插入特定的字串,讓雜湊後的結果和使用原始密碼的雜湊結果不相符,這種過程稱之為“加鹽”。
以上這句話是維基百科上對於 Salt 的定義,但是僅憑這句話還是很難理解什麼叫 Salt,以及它究竟起到什麼作用。
第一代密碼
早期的軟體系統或者網際網路應用,資料庫中設計使用者表的時候,大致是這樣的結構:
mysql> desc User; +----------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +----------+--------------+------+-----+---------+-------+ | UserName | varchar(50) | NO | | | | | PassWord | varchar(150) | NO | | | | +----------+--------------+------+-----+---------+-------+
資料儲存形式如下:
mysql> select * from User; +----------+----------+ | UserName | PassWord | +----------+----------+ | lichao | 123 | | akasuna | 456 | +----------+----------+
主要的關鍵欄位就是這麼兩個,一個是登陸時的使用者名稱,對應的一個密碼,而且那個時候的使用者名稱是明文儲存的,如果你登陸時使用者名稱是 123,那麼資料庫裡存的就是 123。這種設計思路非常簡單,但是缺陷也非常明顯,資料庫一旦洩露,那麼所有使用者名稱和密碼都會洩露,後果非常嚴重。參見 《CSDN 詳解 600 萬使用者密碼洩露始末》。
第二代密碼
為了規避第一代密碼設計的缺陷,聰明的人在資料庫中不在儲存明文密碼,轉而儲存加密後的密碼,典型的加密演算法是 MD5 和 SHA1,其資料表大致是這樣設計的:
mysql> desc User; +----------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +----------+--------------+------+-----+---------+-------+ | UserName | varchar(50) | NO | | | | | PwdHash | char(32) | NO | | | | +----------+--------------+------+-----+---------+-------+
資料儲存形式如下:
mysql> select * from User; +----------+----------------------------------+ | UserName | PwdHash | +----------+----------------------------------+ | lichao | 202cb962ac59075b964b07152d234b70 | | akasuna | 250cf8b51c773f3f8dc8b4be867a9a02 | +----------+----------------------------------+
假如你設定的密碼是 123,那麼資料庫中儲存的就是 202cb962ac59075b964b07152d234b70 或 40bd001563085fc35165329ea1ff5c5ecbdbbeef。當使用者登陸的時候,會把使用者輸入的密碼執行 MD5(或者 SHA1)後再和資料庫就行對比,判斷使用者身份是否合法,這種加密演算法稱為雜湊。
嚴格地說,這種演算法不能算是加密,因為理論上來說,它不能被解密。所以即使資料庫丟失了,但是由於資料庫裡的密碼都是密文,根本無法判斷使用者的原始密碼,所以後果也不算太嚴重。
第三代密碼
本來第二代密碼設計方法已經很不錯了,只要你密碼設定得稍微複雜一點,就幾乎沒有被破解的可能性。但是如果你的密碼設定得不夠複雜,被破解出來的可能性還是比較大的。
好事者收集常用的密碼,然後對他們執行 MD5 或者 SHA1,然後做成一個資料量非常龐大的資料字典,然後對洩露的資料庫中的密碼就行對比,如果你的原始密碼很不幸的被包含在這個資料字典中,那麼花不了多長時間就能把你的原始密碼匹配出來。這個資料字典很容易收集,CSDN 洩露的那 600w 個密碼,就是很好的原始素材。
於是,第三代密碼設計方法誕生,使用者表中多了一個欄位:
mysql> desc User; +----------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +----------+-------------+------+-----+---------+-------+ | UserName | varchar(50) | NO | | | | | Salt | char(50) | NO | | | | | PwdHash | char(32) | NO | | | | +----------+-------------+------+-----+---------+-------+
資料儲存形式如下:
mysql> select * from User; +----------+----------------------------+----------------------------------+ | UserName | Salt | PwdHash | +----------+----------------------------+----------------------------------+ | lichao | 1ck12b13k1jmjxrg1h0129h2lj | 6c22ef52be70e11b6f3bcf0f672c96ce | | akasuna | 1h029kh2lj11jmjxrg13k1c12b | 7128f587d88d6686974d6ef57c193628 | +----------+----------------------------+----------------------------------+
Salt 可以是任意字母、數字、或是字母或數字的組合,但必須是隨機產生的,每個使用者的 Salt 都不一樣,使用者註冊的時候,資料庫中存入的不是明文密碼,也不是簡單的對明文密碼進行雜湊,而是 MD5( 明文密碼 + Salt),也就是說:
MD5('123' + '1ck12b13k1jmjxrg1h0129h2lj') = '6c22ef52be70e11b6f3bcf0f672c96ce' MD5('456' + '1h029kh2lj11jmjxrg13k1c12b') = '7128f587d88d6686974d6ef57c193628'
當使用者登陸的時候,同樣用這種演算法就行驗證。
由於加了 Salt,即便資料庫洩露了,但是由於密碼都是加了 Salt 之後的雜湊,壞人們的資料字典已經無法直接匹配,明文密碼被破解出來的概率也大大降低。
是不是加了 Salt 之後就絕對安全了呢?淡然沒有!壞人們還是可以他們資料字典中的密碼,加上我們洩露資料庫中的 Salt,然後雜湊,然後再匹配。但是由於我們的 Salt 是隨機產生的,假如我們的使用者資料表中有 30w 條資料,資料字典中有 600w 條資料,壞人們如果想要完全覆蓋的壞,他們加上 Salt 後再雜湊的資料字典資料量就應該是 300000* 6000000 = 1800000000000,一萬八千億啊,幹壞事的成本太高了吧。但是如果只是想破解某個使用者的密碼的話,只需為這 600w 條資料加上 Salt,然後雜湊匹配。可見 Salt 雖然大大提高了安全係數,但也並非絕對安全。
實際專案中,Salt 不一定要加在最前面或最後面,也可以插在中間嘛,也可以分開插入,也可以倒序,程式設計時可以靈活調整,都可以使破解的難度指數級增長。
PS,文中所謂第一、二、三代密碼的稱呼,是我自己 YY 的。
相關文章
- 「密碼學」雜湊為什麼要將鹽加在明文後面?密碼學
- 為什麼要在GoDaddy註冊域名Go
- 為什麼還要記密碼密碼
- .NetCore 登入(密碼鹽+隨機數)NetCore密碼隨機
- 為什麼我要在2018年學習Python?Python
- 為什麼要在2021年放棄ExpressJS -DEVExpressJSdev
- 圖 | 程式設計師為什麼非要在車流中改程式碼?程式設計師
- 為什麼我們要在遊戲裡“牽手”?遊戲
- 在密碼學中,“加鹽”(Salting)是指在儲存使用者密碼的雜湊值之前,向原始密碼新增一個隨機生成的字串(稱為“鹽”Salt)的過程。密碼學隨機字串
- 加鹽hash儲存密碼的正確方式密碼
- 直播系統app原始碼,shiro簡單的密碼加鹽與密碼驗證APP原始碼密碼
- 什麼是SSL證書?為什麼要在網站上安裝SSL證書?網站
- 撒點鹽Salt
- [Flutter翻譯]為什麼要在Flutter中使用隔離物?Flutter
- 勒索攻擊為什麼成為了黑產“財富密碼”?密碼
- 面試官:為什麼忘記密碼要重置而不是告訴你原密碼?面試密碼
- minikube master 節點的 docker 使用者的密碼什麼?ASTDocker密碼
- [譯] 為什麼需要在 React 類元件中為事件處理程式繫結 thisReact元件事件
- python_hashlib,md5,getpass, 密碼加密,隱藏,加鹽Python密碼加密
- 維也納MedUni:研究發現食物里加鹽會使患胃癌的風險增加40%
- 國密瀏覽器是什麼?有哪些?有什麼特點?瀏覽器
- 為什麼阿里規定需要在事務註解@Transactional中指定rollbackFor?阿里
- 北極科考:我們為什麼要在北極呆上一年?
- 密碼123456,這意味著什麼?密碼
- win10進入安全模式需要密碼初始密碼是什麼Win10模式密碼
- 為什麼伺服器要在機房的託管下才能更好的執行?伺服器
- 駭客偷你的密碼幹什麼?密碼
- 程式設計沒點為什麼,生活就是十萬個為什麼程式設計
- 資料庫修改密碼需要在系統中改哪些地方資料庫密碼
- 華為“平臺+生態”碩果累累 背後的密碼是什麼?密碼
- 什麼是 unicode 程式碼點Unicode
- PbootCMS的預設賬號密碼是什麼?boot密碼
- Shell 點檔案可以為你做點什麼
- 解讀 | 為什麼要做“密評”?(中科三方)
- 【日記】為什麼非要在 520 這種時間和領導應酬……(673 字)
- 【面試普通人VS高手系列】講一下wait和notify這個為什麼要在synchronized程式碼塊中?面試AIsynchronized
- IT人為什麼也需要懂點FMEA?
- 為什麼說雲原生是企業數字化轉型的通關密碼?密碼
- 如何登入 oss 的賬號密碼是什麼密碼