為什么要在密碼里加點“鹽”

鹽(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 的。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/387038.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/387038.shtml
英文地址,請注明出處:http://en.pswp.cn/news/387038.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

一致性哈希算法 應用

互聯網創業中大部分人都是草根創業,這個時候沒有強勁的服務器,也沒有錢去買很昂貴的海量數據庫。在這樣嚴峻的條件下,一批又一批的創業者從創業中獲得成 功,這個和當前的開源技術、海量數據架構有著必不可分的關系。比如我們使用m…

(9)How to take a picture of a black hole

https://www.ted.com/talks/katie_bouman_what_does_a_black_hole_look_like/transcript 00:13In the movie "Interstellar[??nt?r?stel?(r)]星際的," we get an up-close look at a supermassive black hole. Set against a backdrop of bright gas, the black…

單個節點的緩存容量達到上限 Hash算法一致性

場景 單個節點的緩存容量達到上限,無法繼續單點增加內存,如何解決? 單個節點支撐的QPS達到上限,如何解決? 初步方案 增加N個緩存節點,為了保證緩存數據的均勻,一般情況會采用對key值hash&…

java學習筆記11 (構造方法 this深探)

在開發中,經常需要在創建對象的同事明確對象對的屬性值,比如一個person對象創建的時候就應該有name和age 等屬性,那么如何做到在創建對象的同時給對象的屬性值初始化值呢? 這里介紹構造方法 1 構造方法沒有返回值類型,…

密碼中不能包含全角字符的正則表達式

String regex "^((?![^\\x00-\\xff]).)*$"; String str "aA"; System.out.println(str.matches(regex));

編程算法 - 將排序數組按絕對值大小排序 代碼(java)

一個含有多個元素的數組&#xff0c;有多種排序方式。它可以升序排列&#xff0c;可以降序排列&#xff0c;也可以像我們以前章節說過的&#xff0c;以波浪形方式排序&#xff0c;現在我們要看到的一種是絕對值排序。對于數組A,絕對值排序滿足以下條件&#xff1a;|A[i]| < …

QT Linux打包發布

Linux&#xff1a; 1、用Release編譯&#xff1b; 2、把可執行文件(如paike)放入新建目錄中; 3、當前目錄下編寫腳本copyDependency.sh&#xff0c;把動態鏈接庫導入當前目錄&#xff1b; #!/bin/shexe"paike" #發布的程序名稱destination"/home/paike"…

CRM公海自動回收規則

企微云CRM操作指南 – 道一云|企微https://wbg.do1.com.cn/xueyuan/2568.html 銷售云 - 美洽 - 連接客戶&#xff0c;親密無間https://meiqia.com/sales-cloud 轉載于:https://www.cnblogs.com/rgqancy/p/10695466.html

三分鐘看懂一致性哈希算法

一致性哈希算法&#xff0c;作為分布式計算的數據分配參考&#xff0c;比傳統的取模&#xff0c;劃段都好很多。 在電信計費中&#xff0c;可以作為多臺消息接口機和在線計費主機的分配算法&#xff0c;根據session_id來分配&#xff0c;這樣當計費主機動態伸縮的時候&#xf…

數據結構09圖

第七章 圖 Graph 7.1 圖的定義和術語 頂點 Vertex V 是頂點的有窮非空集合&#xff0c;頂點數 |V| n VR 兩個頂點之間關系的集合&#xff0c;邊數 |VR| e 有向圖 Digraph <v, w> Arc v Tail / Inital node w Head / Terminal node 無向圖 Undigraph <v, w> 必…

JVM調優-GC參數

一、Throughput收集器(吞吐量) -XX:UseParallelGC -XX:UseParallelOldGC *參數調整&#xff1a;通過調整堆大小&#xff0c;減少GC停頓時間&#xff0c;增大吞吐量 增強堆大小可以減少Full GC頻率&#xff0c;但卻會增加停頓時間 1.手動調整 -Xmn -Xms -XX:NewRatioN 手動指…

aspnetcore源碼學習(一)

---恢復內容開始--- 筆者從事netcore相關項目開發已經大半年了&#xff0c;從netcore 1.0到現在3.0大概經過了3年左右的時間&#xff0c;記得netcore剛出來的時候國內相關的學習資料缺乏&#xff0c;限制于外語不大熟練的限制國外的相關書籍看起來相當吃力&#xff0c;于是在當…

評估一個垃圾收集(GC)

在實踐中我們發現對于大多數的應用領域&#xff0c;評估一個垃圾收集(GC)算法如何根據如下兩個標準&#xff1a; 吞吐量越高算法越好暫停時間越短算法越好 首先讓我們來明確垃圾收集(GC)中的兩個術語:吞吐量(throughput)和暫停時間(pause times)。 JVM在專門的線程(GC threads…

python數據分析常用包之Scipy

Scipy轉載于:https://www.cnblogs.com/jacky912/p/10697853.html

docker容器狀態跟蹤及疑惑

一、 1 def status_test():2 container client.containers.create("comp")3 print ("create: ", container.status)4 container.start()5 print ("start: ", container.status)6 container.pause()7 print ("paus…

CAP和BASE理論

幾個名詞解釋&#xff1a; 網絡分區&#xff1a;俗稱“腦裂”。當網絡發生異常情況&#xff0c;導致分布式系統中部分節點之間的網絡延時不斷變大&#xff0c;最終導致組成分布式系統的所有節點中&#xff0c;只有部分節點之間能夠進行正常通信&#xff0c;而另一些節點則不能…

Mysql案例5:取得平均薪資最高的部門的部門名稱

一、要求&#xff1a;查詢平均薪水最高部門的部門編號 二、背景&#xff1a;當前數據庫有employee表和department表&#xff0c;數據分別如下&#xff1a; employee表&#xff1a; department表&#xff1a; 三、難點&#xff1a; 1、需要考慮最高平均薪資可能在多個部門同時出…

Spring 處理過程分析

一、處理過程分析 1、首先&#xff0c;Tomcat每次啟動時都會加載并解析/WEB-INF/web.xml文件&#xff0c;所以可以先從web.xml找突破口&#xff0c;主要代碼如下&#xff1a;<servlet ><servlet-name >spring-mvc</servlet-name><!-- servlet類 --><…

python全棧開發中級班全程筆記(第二模塊、第四章)(常用模塊導入)

python全棧開發筆記第二模塊 第四章 &#xff1a;常用模塊&#xff08;第二部分&#xff09; 一、os 模塊的 詳解 1、os.getcwd() &#xff1a;得到當前工作目錄&#xff0c;即當前python解釋器所在目錄路徑 import os j os.getcwd() # 返回當前pyt…

基于 Spring Cloud 完整的微服務架構實戰

本項目是一個基于 Spring Boot、Spring Cloud、Spring Oauth2 和 Spring Cloud Netflix 等框架構建的微服務項目。 作者&#xff1a;Sheldon地址&#xff1a;https://github.com/zhangxd1989 技術棧 Spring boot - 微服務的入門級微框架&#xff0c;用來簡化 Spring 應用的初…