2010-02-01 77 views
11

我正在爲我們的代碼庫添加哈希摘要生成功能。我希望使用一個字符串作爲散列鹽,以便可以將預先知道的密鑰/密碼短語預置爲需要散列的任何內容。我誤解了這個概念嗎?我誤解了哈希鹽是什麼?

+0

你在寫什麼語言? – 2010-02-01 15:38:21

+0

我正在用Java編寫這個 – 2010-02-01 16:11:04

回答

18

salt是一個隨機元素,它被添加到密碼函數的輸入中,目的是在每次調用時以不同的方式影響處理和輸出。鹽,而不是「鑰匙」,並不意味着保密。一個世紀前,用於加密或認證的加密方法是「祕密的」。然後,隨着計算機的出現,人們意識到保持一種完全祕密的方法是困難的,因爲這意味着保持軟件本身的機密性。一些定期寫入磁盤的東西,或者作爲一些專用硬件而化身,難以保密。因此,研究人員將「方法」分爲兩個不同的概念:(它是公開的併成爲軟件和硬件)和(該算法的參數,僅在處理期間存在於易失性RAM中)。密鑰集中了祕密並且是純數據。當密鑰存儲在人的大腦中時,通常稱其爲「密碼」,因爲人類比單詞更擅長記憶單詞。

然後密鑰本身在稍後分裂。事實證明,爲了正確的加密安全性,我們需要兩件事:一個機密參數和一個可變參數。基本上,重複使用相同的密鑰用於不同的用途往往會造成麻煩;它經常泄露信息。在某些情況下(特別是流密碼,但也用於哈希密碼),它泄漏太多並導致成功的攻擊。所以經常需要可變性,每次密碼方法運行時都會發生變化。現在最好的部分是大多數時候,變化和祕密不需要合併。也就是說,我們可以將機密變量分開。因此,密鑰分爲:

  • 密鑰,通常被稱爲「密鑰」;
  • 一個變量元素,通常隨機選擇,並根據算法類型將其稱爲「salt」或「IV」(如「初始值」)。

只有鑰匙需要保密。可變元素需要所有相關方都知道,但它可以是公開的。這是一件幸事,因爲分享密鑰是困難的;用來分發這種祕密的系統會發現,容納每次運行算法時都會改變的可變部分是很昂貴的。

在存儲散列密碼的情況下,上述說明中變爲:

  • 「重用鍵」是指兩個用戶碰巧選擇了相同的密碼。如果密碼只是散列,那麼兩個用戶將獲得相同的散列值,並顯示。這是泄漏。
  • 同樣,沒有散列,攻擊者可以使用預先計算的表進行快速查找;他也可以同時攻擊數千個密碼。這仍然使用相同的泄漏,只是以一種方式來證明爲什麼這種泄漏是不好的。
  • Salting意味着將一些變量數據添加到散列函數輸入。那個可變數據就是鹽。鹽的要點是兩個不同的用戶應該儘可能使用不同的鹽。但密碼驗證者需要能夠重新計算密碼中的相同散列,因此他們必須有權訪問salt。

由於鹽必須能夠被驗證者訪問,但不一定是保密的,所以通常將salt值與散列值一起存儲。例如,在Linux系統上,我可以使用這個命令:

openssl passwd -1 -salt "zap" "blah" 

此計算一個散列密碼,用散列函數MD5,適合於在/etc/password/etc/shadow文件的使用,對於密碼"blah"和鹽(在這裏,我明確選擇鹽,但在實際條件下應該隨機選擇)。輸出是:

$1$zap$t3KZajBWMA7dVxwut6y921 

其中美元符號作爲分隔符。最初的"1"標識哈希方法(MD5)。鹽在那裏,用明文表示。最後一部分是散列函數輸出。

關於如何將salt和密碼作爲哈希函數的輸入發送(至少在glibc源代碼中,可能在別處),有一個規範(某處)。

編輯:在「登錄和密碼」的用戶認證系統,「登錄」可以作爲一個差強人意鹽(兩個不同的用戶會有不同的登錄),但是這並沒有抓住給定的情況用戶更改密碼(新密碼是否與舊密碼相同將會泄漏)。

+1

「鹽,而不是」鑰匙「,並不意味着保密。」 - 使用像MD5或SHA-1這樣的衆所周知的單向散列函數,你必須保持鹽的機密性,否則強制顛倒你的散列函數就容易多了。 – Paolo 2010-02-01 16:33:00

+0

如果鹽是保密的,它不是鹽,而是鹽的一部分。現在恰好在哈希密碼設置中,鹽可以完成它的工作(它可以防止相同的密碼和並行攻擊泄漏),但這不夠好,因爲人們在選擇和記住好的密碼時很可悲。因此,習慣上試圖保持整個輸出爲「受保護」('/ etc/shadow'不公開可讀);額外的安全來自隱藏散列輸出,而不是隱藏鹽。無論哪種方式,驗證者必須仍然可以訪問salt和散列輸出。 – 2010-02-02 13:31:30

3

你正在理解這個概念。只要確保預先加入的鹽每次都是可重複的。

2

如果我正確地理解了你的話,這聽起來就像你說得對。該過程的僞代碼看起來像這樣:

string saltedValue = plainTextValue + saltString; 
// or string saltedalue = saltString + plainTextValue; 

Hash(saltedValue); 

鹽只是爲試圖獲取您的信息的人增加了另一層級的複雜性。

0

如果鹽對於每個加密短語都不同,它會更好,因爲每個鹽都需要自己的彩虹表。

0

值得一提的是,即使鹽的密碼用法不同,您的鹽也不應該從密碼本身計算出來!這類事情的實際結果是完全無效的安全性。