2013-11-09 64 views
6

我在PHP密碼的安全性讀書了,我偶然發現了一個有趣的說法:爲什麼字符串與它的散列哈希,因爲鹽返回散列?

散列其哈希密碼鹽返回相同的哈希

沒有太多的想法,我去在php.net,發現這是說同樣的事情。

讓我們來看一個例子:

crypt("test", "test"); -> teH0wLIpW0gyQ 
crypt("test", "teH0wLIpW0gyQ"); -> teH0wLIpW0gyQ 

我完全可以理解的PHP隱窩產生給定的字符串的單向散列。

  1. 我不明白的是我們如何使用兩種完全不同的鹽來獲得相同的散列輸出?
  2. 這是否意味着可能有其他鹽可能會給我相同的散列?

跟進

謝謝大家的指針。我現在可以看到,默認行爲是隻使用鹽的前兩個字符,這完全回答了我的所有問題。感覺像一個愚蠢的事情,但...

+0

由於鴿子的原理,對#2的回答很平常。這影響幾乎所有以散列爲基礎的構建,並且在精心設計的系統中不會產生問題,因爲*生成相同散列的輸入*都不可以猜測或發現。 – delnan

+0

#1的答案是:它取決於密碼算法。這個問題沒有普遍的答案。我不知道'crypt'函數的基本工作原理,但即使我這樣做了,我也懷疑它只是一個簡短的答案;-) –

+0

一般來說,是的;可以有一個以上的鹽會給出相同的散列,但是對於一個潤滑良好的網站,這不應該是引起關注的主要原因 –

回答

3

1。我不明白的是,我們如何使用兩種完全不同的鹽來獲得相同的散列輸出?

儘管您爲crypt函數提供了不同的鹽,但它在內部使用相同的鹽,即i。例如,te。這是由於crypt是如何實現的:

基於DES-標準的哈希從字母「./0-9A-Za-z」兩個字符的鹽。

所以,即使你提供的鹽超過2個字符,它只會採取前兩個。

並且因爲crypt的輸出包含所計算散列前面使用的鹽,所以使用crypt散列作爲鹽導致完全相同的輸出。而這僅僅是完美的,因爲那麼下面可以用來驗證存儲的密碼:

crypt($password, $hash) === $hash 


2。這是否意味着可能有其他鹽可能會給我相同的散列?

是的。 This does also apply to other crypt algorithms like bcrypt.

4

這是有意的。你的crypt函數,當第二個參數由字母和數字組成時,只使用兩個「salt」的第一個字符進行加密,而這兩個字符放在結果的開頭。 所以,

crypt("test", "test");  -> teH0wLIpW0gyQ 
crypt("test", "te");   -> teH0wLIpW0gyQ 
crypt("test", "tea");   -> teH0wLIpW0gyQ 
crypt("test", "temperature"); -> teH0wLIpW0gyQ 
etc. 

這是方便密碼的正確性檢查完成,使
crypt($password, crypt($password, $salt)) == crypt($password, $salt)