2012-04-28 76 views
1

當存儲密碼時,據說Salt不需要保密,而且唯一的目的是保持所有哈希都是唯一的。還有人說,限制密碼長度並不是一個好的做法,但考慮這個例子:保持內部密碼長度一致,並保持鹽的祕密?

在散列之前,我們通過將用戶輸入修剪爲最大值100來確保純文本版本始終爲128個字符,然後將附加字符作爲我們的鹽。

因此,如果用戶輸入20個字符,我們追加108個隨機字符作爲鹽。如果用戶輸入100,我們追加28,依此類推。重點是,純文本版本的長度應該是128個字符。在代碼中它可能是這樣的:

$salt = generate_salt($pass); // length varies as explained above 
$hash = hash('sha512', $pass.$salt); 

這樣,我們的「純文本」散列之前將永遠是128個字符。

我們儲存在服務器A $哈希值和$鹽存儲服務器B上

現在讓我們假設攻擊者獲得對哈希DB(服務器A),並設法扭轉哈希值。對他來說看起來不錯,但他看到的純文本版本(或反轉哈希)仍然看起來像哈希,因爲它是128個字符。由於他不知道鹽,他永遠不會知道原始密碼。

作爲一個額外的挑戰,由於SHA512產生128個字符的事實,他也不能確定他是否已經到達純文本版本,因爲(如前所述)純文本版本看起來像哈希。顯而易見,他可能認爲這是一個迭代版本,如果是這樣的話,他可能會無限期地繼續迭代。

是否有使用這種方法的任何問題,因爲在哈希逆轉的情況下,保持鹽祕密提供額外的安全性,並保持純文本的長度均勻無疑增加了混淆層?

注:這當然是假定您的應用程序有多個失敗的登錄檢測/防禦。

+0

散列的一點是你不能倒過來。 – zimdanen 2012-04-30 13:33:06

+0

@zimdanen同意,但它通過彩虹/字典攻擊是「可逆的」 – IMB 2012-04-30 14:10:48

+0

這就是爲什麼你想要一個鹽,但是,正如你和答案所提到的,鹽不需要保密。散列本身將保持數據的祕密;鹽只會增加計算彩虹桌的複雜性。 – zimdanen 2012-04-30 14:13:08

回答

0

鹽並不需要是祕密的,它的唯一目的就是讓所有的hash獨特

這也使得它更慢「暴力破解哈希表,因爲你需要每一個嘗試每一個哈希+鹽組合而不是僅僅嘗試一個哈希整個表('select * from passwords where hash ='xxx'')

保持鹽的祕密給予額外的安全性,並且,保持純文本長度統一可以說增加了一層混淆?

事實上,你的'顛倒的哈希'看起來像哈希不會增加真正的額外安全性(它實際上只是安全的默默無聞)。您的網絡服務器將需要連接到服務器A 服務器B(用於驗證用戶/密碼組合),因此當該服務器受到威脅時,所有希望都將丟失。

您可能會感興趣的文章this blog post by Jeff Atwood。 (編輯:貼錯codinghorror鏈接)

+0

我同意整個問題是減緩哈希反轉,並且我相信添加「默默無聞的安全性」會在原始加密哈希上添加額外的緩慢層。這裏的要點是在整個磨難期間讓攻擊者的頭部疼痛。 – IMB 2012-04-29 08:19:16

+0

所有的希望都不容易丟失,因爲攻擊者必須進入幾個牆壁:1.妥協服務器A. 2.妥協服務器B. 3.妥協應用程序代碼。 4.反轉哈希。 5.找出鹽和哈希之間的關係。 6.如果他發現App代碼會截斷/附加一堆隨機字符,他最終會意識到他永遠不會知道原始用戶密碼。現在我不確定其他人,但這個過程非常緩慢。 – IMB 2012-04-29 08:24:31

3

首先,除非你真的知道你在做什麼,不要發明你自己的密碼系統。

使用現有的(像PBKDF2bcrypt或scrypt),它們具有優於簡單鹽醃哈希的優點,因爲它們使用更多的CPU時間(所有三個)和/或存儲器(後兩者),這使得並行昂貴。

哈希中的鹽只保護彩虹表,而不是針對暴力攻擊!

如果攻擊者管理反轉散列,他將獲得$pass.$salt(因此,密碼)的知識。

鹽的目的是爲了避免彩虹表的廉價創建,也就是說,不是隻計算每個可能的密碼的哈希值,並將它們與數據庫進行比較,攻擊者必須爲每個不同的鹽做這個。

保持鹽的祕密具有使攻擊更加昂貴的理論優勢,因爲攻擊者還必須嘗試每種可能的密碼嘗試每種可能的鹽。

然而在實踐中,他可能能夠訪問服務器B,一旦他能夠訪問服務器A.

如果事情看起來像一個哈希可能並不重要。一旦服務器受到攻擊,攻擊者可能會發現使用了哪些混淆技術。

附註:SHA-512產生512位輸出,它們是64個ASCII字符。

+0

我沒有發明任何東西,SHA512就是這個例子使用的。我只是在其上添加更高級別的實現。在這個例子中,潛在的密碼散列是SHA512,這意味着我可以用bcrypt等代替它。 – IMB 2012-04-29 08:28:59

+0

他獲得'$ pass。$ salt',但系統在原始傳遞中截斷/追加隨機字符,永遠隱藏原始傳遞。他也不知道鹽是什麼,所以他很難確定鹽開始的位置。 – IMB 2012-04-29 08:31:17

+0

即使所有的希望都失去了,這個例子仍然假設:即:整個系統都被破壞了。攻擊者永遠不會知道原始密碼,因爲原始密碼被截斷/附加,因此如果在其他系統(如Facebook/Banking/Email /等)中嘗試,則無用。 – IMB 2012-04-29 08:34:46

1

這種方法的第一個問題是您正在實現自己的加密代碼。這幾乎總是一個壞主意;加密非常困難,並且很容易以微妙的方式搞砸,而其他人花費了大量的時間和精力來實現構建於其之上的加密基元和服務,以便您不必這樣做。但讓我們假設爲了爭辯,你確實需要這樣做:-)。

第二件事是你截斷用戶的輸入 - 扔掉寶貴的熵 - 沒有任何好處。你準備產生多達128個字符的鹽;爲什麼不總是這樣做,並將它們(連同密碼一起)放入你的哈希中?通過截斷獲得什麼?我看到的唯一答案是,假設原來的密碼「看起來像哈希,因爲它是128個字符」,但事實並非如此;你的醃製密碼仍然以實際密碼數據開始,通常看起來與哈希不同。

第三件事 - 這可能只是我的錯誤,正確地閱讀你的想法 - 是不清楚你的鹽是從哪裏來的。你將它們描述爲「隨機」,並說攻擊者不會知道它們;但那麼你的認證系統如何得到它們呢?看起來他們是從密碼中派生出來的,但在這種情況下,salting-plus-hashing只是一個稍微複雜的哈希函數,你並沒有真正獲得任何東西。

你明顯拒絕(或可能沒有遇到)的一般原則是:總是設計密碼系統時假設攻擊者知道他們可能知道的一切,包括所有你的源代碼。這是一個很好的原則,你不應該拒絕它。依靠一個小小的「額外混淆層」並不能很好地爲您服務;在最壞的情況下,它會使錯誤更容易(通過使系統複雜化)並誘發錯誤的安全感。

+0

首先,我沒有實現我自己的密碼,這個例子使用SHA512。 – IMB 2012-04-29 07:59:53

+0

其次,目的是截斷然後附加隨機數據(它增加了自定義熵),因此修改了實際的密碼。由於原始用戶密碼被截斷/附加,因此用戶使用相同的密碼時,它將無法在Facebook上使用。第三,salt被生成並保存在服務器B中。要進行身份驗證,應用程序將截斷輸入,從服務器B獲取salt並比較哈希。 – IMB 2012-04-29 08:06:46

+0

我同意一般原則,但這個例子假設只有散列表被泄露。如果整個系統確實受到了威脅,那麼顛倒散列表就沒用了,因爲攻擊者基本上獲得了他需要的所有信息。這個例子假設在散列表顛倒的情況下,原始用戶密碼將永遠不會被顯示,因爲系統會截斷/附加它。攻擊者能夠完全恢復原始密碼的唯一機會是他能夠竊取包括服務器A,服務器B和應用程序代碼在內的所有系統。 – IMB 2012-04-29 08:12:02