密碼安全性

## 讀書筆記之 <<密碼安全性>>

 

### 什麼是密碼哈希?

- 哈希算法: 將任何數量的數據轉換爲無法反轉的固定長度的“指紋”(即使輸入的變化很小,但生成的哈希值將完全不同)。

 

用於實現諸如哈希表之類的數據結構的哈希函數被設計爲快速,不安全的。 僅加密哈希函數可用於實現密碼哈希。 諸如SHA256,SHA512,RipeMD和WHIRLPOOL之類的哈希函數是加密哈希函數。


 

### 密碼存儲有幾種方式:

- 直接存儲密碼明文m

- 存儲密碼明文的哈希值hash(m)

- 存儲密碼明文的加鹽哈希 hash(m+salt),這裏的salt可以是用戶名,手機號等,但必須保證每個用戶的salt都不一樣纔是安全的。


 

### 破解哈希:

- 嘗試猜測密碼(最簡單的方法),對每個猜測進行哈希處理,並檢查猜測的哈希是否等於被破解的哈希。 如果哈希值相等,則猜測爲密碼。

 

#### 猜測密碼:

- 字典攻擊: 使用的文件包含單詞,詞組,常用密碼以及其他可能用作密碼的字符串。文件中的每個單詞都經過哈希處理,並將其哈希值與密碼哈希值進行比較。 若匹配,則該單詞爲密碼。這些字典文件是通過從大量文本甚至是密碼的真實數據庫中提取單詞來構造的。

 

- 蠻力攻擊(列舉所有字符串) : 嘗試所有可能的字符組合,直到給定的長度。 這種攻擊在計算上非常昂貴,並且效率最低,但最終會找到密碼。所以密碼應該足夠長,以至於搜索所有可能的字符串以找到它會花費很長時間。

 

- 注: 沒有辦法阻止字典攻擊或蠻力攻擊。 即可以使它們的有效性降低,但是沒有辦法完全阻止它們。 如果您的密碼哈希系統是安全的,那麼破解哈希的唯一方法是對每個哈希運行字典或蠻力攻擊。

 

#### Tables

- 單純地通過導入字典,採用和目標同等算法破解,其速度其實是非常緩慢的。之後通過大量的嘗試和總結,發現若能夠實現直接建立出一個數據文件,裏面事先記錄了採用和目標採用同樣算法計算後生成的Hash散列數值,在需要破解的時候直接調用這樣的文件進行比對,破解效率就可以大幅度地,甚至成百近千近萬倍地提高,這樣事先構造的Hash散列數據文件在安全界被稱之爲Table表(文件)。

 

#### 查找表

- 一種非常有效的方法,可以非常快速地破解許多相同類型的哈希。總體思路是在密碼字典中預先計算密碼的哈希值,並將它們及其對應的密碼存儲在查找表數據結構中。 一個好的查找表可以實現即使包含數十億個哈希,也可以每秒處理數百個哈希查找。

 

#### 反向查詢表

- 這種方式可以讓攻擊者不需要預先計算一個查詢表的情況下同時對大量hash進行字典和暴力破解攻擊。首先,攻擊者會根據從數據庫獲取到的數據製作一個密碼和用戶名(一對多)對應的hash表。然後將常見的字典密碼進行hash之後,跟這個表的hash進行對比,就可以知道用哪些用戶使用了這個密碼。這種攻擊方式很有效果,因爲通常情況下很多用戶都會有使用相同的密碼。

 

#### 彩虹表(Rainbow Table)

- 不是密碼-->明文 的簡單存儲,以時間換空間。是現在破解哈希常用的辦法。

 

(一) Rainbow Table的原理

- 存儲所有的明文-密碼所需要空間太大,因此提出了一種以計算時間降低存儲空間的辦法:“預計算的哈希鏈集”。

 

(二) 預計算的哈希鏈集

- 例如: 一條k=2哈希鏈: aaaaaa--->(H)281DAF40--->(R)sgfnyd--->(H)920ECF10--->(R)kiebgt

- H函數就是要破解的哈希函數。約簡函數R是構建這條鏈的時候定義的一個函數:它的值域和定義域與H函數相反。通過該函數可以將哈希值約簡爲一個與原文相同格式的值。

- 這條鏈是這樣生成的:隨機選擇一個明文aaaaaa,對其求哈希得到281DAF40,R(281DAF40) 得到另外一個明文sgfnyd。,繼續重複2,3步驟,存儲的時候,不需要存儲所有的節點,只需要存儲每條鏈的頭尾節點(這裏是aaaaaa和kiebgt),以大量的隨機明文作爲起節點,通過上述步驟計算出哈希鏈並將終節點進行儲存,可得到一張哈希鏈集。

 

(三) 預計算的哈希鏈集的使用

- 要破解一個hash值:

(1) 假設其剛好是920ECF10:首先對其進行一次R運算,得到kiebgt,然後發現剛好命中了哈希鏈集中的(aaaaaa,kiebgt)鏈條。可以確定其極大概率在這個鏈條中。於是從aaaaaa開始重複哈希鏈的計算過程,發現sgfnyd的哈希結果剛好是920ECF10,於是破解成功。

(2) 密文不是“920ECF10”而是“281DAF40”:第一次R運算後的結果並未在末節點中找到,則再重複一次H運算+R運算,這時又得到了末節點中的值“kiebgt”。於是再從頭開始運算,可知aaaaaa剛好可哈希值爲281DAF40。

(3) 如是重複了k(=2)次之後,仍然沒有在末節點中找到對應的值,則破解失敗。

 

(四) 預計算的哈希鏈集的意義

- 對於一個長度爲k的預計算的哈希鏈集,每次破解計算次數不超過k,因此比暴力破解大大節約時間。

- 每條鏈只保存起節點和末節點,儲存空間只需約1/k,因而大大節約了空間。


 

### 加鹽

- 通過在散列之前將一個隨機字符串(稱爲salt)附加或添加到密碼上來使哈希隨機化。salt通常與哈希一起存儲在用戶帳戶數據庫中,或者作爲哈希字符串本身的一部分存儲在用戶帳戶數據庫中。僅通過將散列隨機化,查找表,反向查找表和Rainbow表就失效了。因爲攻擊者不會預先知道salt,因此他們無法預先計算查找表或彩虹表。若每個用戶的密碼都用不同的salt進行哈希處理,則反向查找表攻擊也將不起作用。

 

### 鹽實現錯誤:

 

(一) 鹽再利用

- 一個常見的錯誤是在每個哈希中使用相同的鹽。鹽要麼被硬編碼到程序中,要麼被隨機生成一次。 這是無效的,因爲如果兩個用戶使用相同的密碼,則它們仍將具有相同的哈希值。 攻擊者仍然可以使用反向查找表攻擊對每個哈希同時運行字典攻擊。 他們只需要在對每個密碼猜測進行哈希處理之前就應用鹽。如果將鹽硬編碼爲流行產品,則可以爲該鹽建立查找表和彩虹表,以使其更容易破解該產品生成的哈希。因此每次用戶創建帳戶或更改密碼時,都必須生成新的隨機鹽。 

 

(二) 短鹽

- 如果鹽太短,攻擊者可以爲每種可能的鹽建立查找表。 

- 用戶名不應該用作鹽。 用戶名對於單個服務可能是唯一的,但是它們是可預測的,並且經常被其他服務上的帳戶重用。攻擊者可以爲常見的用戶名建立查找表,並使用它們來破解用戶名鹽漬的哈希。

- 爲了使攻擊者無法爲每種可能的鹽創建查找表,鹽必須很長。一個好的經驗法則是使用與哈希函數輸出大小相同的鹽。例如,SHA256的輸出爲256位(32字節),因此鹽值至少應爲32個隨機字節。 


 

### 如何正確地哈希

 

#### 用鹽散列

- 應使用加密安全的僞隨機數生成器 (CSPRNG)生成鹽。

- 鹽值必須是每個用戶每個密碼唯一的。每次用戶創建帳戶或更改密碼時,都應使用新的隨機鹽對密碼進行哈希處理。切勿重複使用鹽。鹽也需要很長,以便有很多可能的鹽。根據經驗,鹽至少與哈希函數的輸出一樣長。鹽應與哈希一起存儲在用戶帳戶表中。

 

#### 儲存密碼

- 使用CSPRNG生成長隨機鹽。

- 將鹽添加到密碼中,並使用標準密碼哈希函數(例如Argon2,bcrypt,scrypt或PBKDF2)對其進行哈希處理。

- 將鹽和哈希值都保存在用戶的數據庫記錄中。 

 

#### 驗證密碼

- 從數據庫中檢索用戶的鹽和哈希值。

- 將鹽添加到給定的密碼之前,並使用相同的哈希函數對其進行哈希處理。

- 將給定密碼的哈希值與數據庫中的哈希值進行比較。如果它們匹配,則密碼正確。否則,密碼錯誤。 

 

參考資料:

- https://www.jianshu.com/p/732d9d960411

- http://www.ha97.com/4009.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章