題:
有人不儲存鹽嗎?
jazzpi
2016-07-15 14:33:58 UTC
view on stackexchange narkive permalink

今天我們在課堂上討論了密碼哈希和加鹽處理。我們的教授對我的鹽的用例有完全不同的理解,並說您可能根本不存儲鹽,而只是檢查所有可能的鹽的每次登錄嘗試並授權是否匹配。

I因為現在我的服務更容易受到蠻力攻擊(發送一個密碼,服務器檢查許多密碼),因此我對此服務沒有任何實質性的了解,但是我猜想它對散列密碼的純字典式攻擊更為安全。

那麼有沒有用例人們會真正做到這一點?

考慮到鹽的長度,如果您必須嘗試所有可能的鹽值,這可能會導致非常冗長(不切實際)的登錄操作。這將導致使用較小的鹽範圍以提高可用性。我認為與使用有效的鹽值並將其存儲相比,這可能導致更差的安全性。另請參閱https://stackoverflow.com/questions/184112/what-is-the-optimal-length-for-user-password-salt,以獲取有關理想鹽長度的討論,建議長度在16到256位之間。
絕對是我們使用的是12位鹽,因此只有4096次嘗試,但是更長的鹽不僅意味著更長的登錄時間,而且還因為服務器嘗試使用2 ^ n個密碼(而不只是一個密碼)對您進行身份驗證而降低了安全性。
這位教授到底是做什麼的?牙科?
請注意,良好的加密哈希在設計上“慢”了,因此可能的鹽值範圍很快就會變得太大。
這就是為什麼人們應該向Stack Exchange學習而不是向教授學習。:-)
如果您的登錄過程涉及強行強制...您做錯了事。不使用鹽(可怕的想法)和嘗試所有鹽(可怕的想法)之間的唯一區別是,這將在計算上變得更加昂貴(惹惱了用戶)。
如果數據庫在潮濕的地方,AFAIK儲存鹽是個壞主意-會導致腐蝕(請參見《第二人生》中腐蝕表的示例[here](https://slm-assets0.secondlife.com/assets/1123356/lightbox / 65b45b42685a44ca64e556f353d48e4e.jpg?1277194741))。
當我在HNQ中看到它時,我以為這是在Cooking.SE上,然後才注意到小“ InfoSec”圖標:D
@oɔɯǝɹ:一般密碼哈希函數在設計上應為_fast_。這就是為什麼不應將常規哈希函數用於密碼哈希!
@cat哈哈,我也是。
您的教授應閱讀:http://stackoverflow.com/questions/1645161/salt-generation-and-open-source-software/1645190#1645190
“ @CaffeineAddiction:”不使用鹽(可怕的想法)和嘗試所有鹽(可怕的想法)之間的唯一區別是,它將在計算上變得更加昂貴(惹惱了用戶)。 實際上,嘗試所有的鹽甚至更糟,因為您現在(以jazzpi為例)遇到哈希衝突的可能性是4096倍。如果具有不同鹽的字典單詞生成相同的哈希,則擁有超級安全的密碼無關緊要。根據已知數據忘記暴力行為;這實際上會使您的應用程序安全性降低,根本沒有已知數據。
稍微偏離主題推薦。首先,確認您在此處寫的內容實際上就是教授所說的內容。如果是這樣,那麼我建議您與學校的院長聯繫,以了解有關轉學/退款的信息。這個人沒有資格教那堂課。
可能您的教授只是簡單地說可以不儲存鹽而是不說這是個好主意嗎?
@Shadur可能是喜劇。
使用胡椒粉可能會引起一些混淆嗎?-即應用程序已知但未與密碼一起存儲在數據庫中的鹽?
@Jedi,男孩,我確實花了很長時間才明白這一點。:)起初我完全忽略了它。
您的教授聽起來像他/他不知道他們在說什麼。如果您問他在哈希之前添加一些咖啡因的想法,那會很有趣。
九 答案:
Gudradain
2016-07-15 17:29:34 UTC
view on stackexchange narkive permalink

不存儲鹽是一個壞建議。

鹽的主要目的是必須分別攻擊每個用戶密碼。

如果不存儲鹽,則就像您說的那樣,您需要嘗試每種單一的鹽組合才能驗證密碼。如果需要檢查每種鹽組合,則意味著鹽不能太長(在註釋中提到了12位)。如果加鹽時間不長,則表示將對許多用戶重複加鹽。如果對許多用戶重複此操作,則意味著攻擊者將能夠同時攻擊許多用戶,這將節省攻擊者的時間。

這樣做,您幾乎完全無法實現使用a鹽。

難道還不存在更多衝突和更多誤報的可能性嗎?
@CaffeineAddiction也許。例如,可能發生以下情況:哈希(錯誤的鹽+正確的密碼)=哈希(正確的鹽+正確的密碼)。但這不是實際的攻擊方法,因為在哈希函數中創建衝突非常困難。
@CaffeineAddiction:不太可能。假設使用SHA-256和32位鹽,那麼您與現有哈希(又稱第二原像)發生衝突的機率從2 ^ -256變為2 ^ -224。在事物的宏偉方案中,更大但仍然是無限的。
@David怎麼樣?哈希函數可以建模為任意兩個輸入都導致獨立輸出的隨機預言機,因此我認為概率根本不會改變(除非您將輸入填充到固定長度)
@Thomas:是的,但是如果系統嘗試使用2 ^ 32種鹽,則每次碰撞的可能性均保持不變,但“任何”碰撞的總概率應降低2 ^ 32。
@Thomas您有一個從<< salt> `生成的哈希。每次用戶輸入密碼時,服務器都會檢查您的密碼以及2 ^ 32種可能的密碼。例如,如果您使用的是32位哈希,則意味著您的真實密碼可以使用,但是如果輸入_any_密碼,則哈希很有可能與服務器嘗試的2 ^ 32之一匹配。
@David您已經忘記了生日悖論的教訓。隨機過程比這更頻繁地發生衝突。實際賠率從2 ^ -256變為2 ^ -193。那是一個用戶。當您添加用戶時,它會保持快速攀升。不過,最終仍然很小。
請記住,誤報對於攻擊者也是有利的。如果他們找到適用於其他鹽的其他密碼,則可以使用它。由於所有鹽都經過嘗試,因此它們仍然可以進行身份驗證。
@AaronDufour,生日悖論僅在您在數據集中尋找衝突時才適用。這實際上更像是原像攻擊-他們正在尋求匹配固定值。
amccormack
2016-07-15 19:14:41 UTC
view on stackexchange narkive permalink

一種“秘密”鹽被稱為胡椒

來自維基百科:

可以在以下位置將胡椒添加到密碼中:除了鹽值。胡椒粉與鹽的作用相似,但是鹽通常與散列的值一起存儲,對於要定義為胡椒粉的東西,它應滿足以下條件之一,將其定義為更精心隱藏的“秘密”比鹽值高:

  • 將胡椒與要散列的值分開保存
  • 為要散列的每個值隨機生成胡椒(在一組有限的值),並且永遠不會存儲。當針對匹配的哈希值測試數據時,這是通過迭代對胡椒有效的一組值來完成的,然後依次將每個值添加到要測試的數據中(通常通過將其後綴添加到數據中),在對組合值運行加密哈希函數之前。

Pepper的優點是,攻擊者現在必須猜測多達Pepper值的可能排列數量

胡椒粉會增加針對特定哈希的攻擊時間,而鹽則不會。

請記住,鹽是緩解預計算哈希的有效方法,它會使攻擊者花費很長時間攻擊一組哈希。但是,如果僅考慮一個散列,並且不使用任何預先計算的散列,則鹽不會增加攻擊時間。但是,Pepper迫使攻擊者對每個純文本密碼使用多個猜測,即使是單個哈希也是如此。

這樣,胡椒類似於鍵拉伸

大多數實現方式都比胡椒更喜歡鍵拉伸。

我的個人觀察是,大多數實現方式都喜歡用鍵拉伸而不是胡椒。我沒有相關參考,因此讀者可以在評論中提供支持或反對的參考。人們傾向於使用鍵拉伸,因為它具有已知和預期的性能成本和安全性好處。為了計算哈希的第N輪,必須計算N個哈希。但是,使用胡椒粉只能計算出預期的嘗試次數。考慮一個1字節的胡椒,攻擊者將需要256個猜測才能猜測所有可能的組合,但是期望值為128,並且攻擊者可以(平均1/256倍)猜測第一次嘗試。

辣椒和鍵拉伸可以相互配合。

鍵拉伸很有效,因為您可以根據希望計算哈希的時間長度來設置回合數採取。假設您希望在當前硬件上進行一次檢查要花費半秒鐘,那麼您只需增加回合數即可,直到出現這種情況為止。

對於胡椒,因為您需要為每個密碼猜測多個值,所以胡椒的大小必須與輪數成反比,以保持計算時間恆定。

關於哈希實現的實用建議

關於密碼/哈希實現的最佳建議是使用眾所周知的方法和經過測試的庫。您應該使用 bcrypt pbkdf2並加上獨特的鹽和許多發子彈。這些算法傾向於以多種語言和框架實現眾所周知的實現。如果您碰巧找到了一個著名的經過測試的庫,其中除了鹽和鍵拉伸之外還包含胡椒,可能值得您花些時間使用,但是額外的好處通常會超過性能成本。

難道還不存在更多衝突和更多誤報的可能性嗎?
-1
辣椒仍然存儲(不是在普通視圖中,而是存儲)
@WoJ Wikipedia文章中的第二個要點指出,可能沒有存儲胡椒。我試圖找到比描述胡椒的Wikipedia更好的參考文獻,但是找不到。如果您知道有建議用來存放胡椒粉的參考文獻,我將很高興為您提供幫助。
@amccormack:,我沒有閱讀Wikipedia文章,對不起。話雖如此,但我從未見過如此實現的胡椒(目睹了數量有限)。檢查哈希算法是否正確(緩慢,多輪)將是一場噩夢。
@Woj,我同意,這將成為測試的噩夢,並且可能導致實現者減少任何關鍵擴展的回合次數。存儲鹽(或確定性地進行計算)將減輕對鍵擴展的負面影響,並可以減輕某些僅散列+鹽值洩漏的情況。
我一直聽到的“胡椒粉”定義是一種鹽,它按應用程序存儲在代碼中,而不是按用戶存儲在數據庫中。
值得一提的是,胡椒仍然存儲在數據庫中,而不必存儲。OP似乎在談論根本不存儲鹽的情況,並且每次嘗試登錄時,應用程序本質上都會強制使用鹽...
@Ajedi32感謝您指出這一點。其他人也指出了這一點,但我找不到明確的消息來源。如果您能指出我的觀點,我將不勝感激。
-1
關於在“ crypto.SE”上定義“ pepper”一詞的參考:[是否存在對密碼術語“ pepper”的現有授權定義?](https://crypto.stackexchange.com/q/24698/23581),[哈希函數中“ pepper”的定義](https://crypto.stackexchange.com/q/20578/23581)。我對後者給出的答案表示讚賞,在後者中,胡椒大多被定義為攻擊者未知的補充秘密,並且人們實際上並不關心這個秘密是否經過硬編碼/計算/等。只要攻擊者仍然不知道。
@Ajedi32,在我問這個問題時,“辣椒”一詞根本沒有被廣泛使用,但是我沒有發明這個詞,幾年前我在紙上的某個地方讀過它。
我以為胡椒粉是按應用程序存儲在數據庫外部的鹽。
胡椒有趣的是,可以並行測試胡椒的值,但是必須依次執行更多輪的哈希處理。
還應提及scrypt(https://en.wikipedia.org/wiki/Scrypt)作為一種合理的選擇。
*“也許值得您花一會兒時間使用它,但是額外的好處通常會超過性能成本。” *“但是”一詞是那句話的錯字,還是我誤解了?似乎應該說“因為”。
Bryan Field
2016-07-15 18:37:58 UTC
view on stackexchange narkive permalink

背景:您應該使用慢速密碼哈希。 (即bcrypt)“慢”是指在計算上很昂貴,需要花費100毫秒以上的時間(在您的硬件上)使用DoS保護* sups來測試單個密碼。如果散列被盜,這將增加通過蠻力查找密碼所需的處理能力(在攻擊者硬件上)。

每用戶唯一鹽是極力推薦的。 (對於bcrypt,它是自動生成的)Salt應該是高度 unique (即長&隨機的),但不是秘密。使用唯一的鹽意味著攻擊者必須為每個用戶運行單獨的蠻力作業

如果沒有“鹽”,攻擊者可以立即使用彩虹表,根本沒有蠻力。

如果僅使用“共享鹽”,那麼攻擊者可能會用單個蠻力破解所有用戶的密碼強迫喬布。 (不如彩虹表快,但比每個單獨的蠻力作業要容易得多)


答案:如果您要“不存儲”鹽(如您的教授所建議的,“用強力在運行時進行哈希處理”)

  • 可能的鹽必須非常少
  • 散列必須要很多更快

,這將完全違反 Salt的目的,嚴重削弱了Slow hash的優勢。那是您教授的主要設計錯誤。基本上,他是推行自己的密碼存儲方案,在該方案中,他應該使用經過嚴格審查的 bcrypt算法(或 scrypt PBKDF2原定使用的地方


*正如 @Navin所說,這可能是潛在的DoS攻擊媒介。一種解決方案是限制每個IP和每個用戶名每小時的嘗試次數。您還可以將散列的“慢度”降低到僅10ms。從“被竊取的散列”的角度來看,這不及100ms,但仍然比“微秒”更好。 sub>

“如果不加鹽,攻擊者可以在一個蠻力作業中將所有用戶的哈希值暴力破解。(這樣可以節省很多時間)”,或者只是從數據庫中為每個用戶選擇MD5哈希值5f4dcc3b5aa765d61d8327deb882cf99,它對應於密碼“ password”。這也是一種保護用戶免受自身傷害的方法。
切勿使用MD5儲存密碼!請改用慢散列。但是,是的,我明白你的意思。我已經更新了引用您所引用的Rainbow Tables的答案。
真正。在現實世界中,無論您使用哪種語言,都應該使用正確的密碼哈希庫,該庫通常在哈希字符串中包含鹽,並防止計時攻擊,這使整個討論變得毫無意義。但是,是的,MD5不是密碼。
Steve Sether
2016-07-15 18:37:46 UTC
view on stackexchange narkive permalink

您的教授是不正確的。加鹽的目的是增加散列密碼的熵,以防止對其進行任何預計算攻擊,並防止來自不同用戶的相同密碼具有相同的散列值。

能夠嘗試所有可能的鹽值意味著鹽中的熵必須非常低,這意味著可以通過彩虹表進行預計算。

Cort Ammon
2016-07-16 03:07:46 UTC
view on stackexchange narkive permalink

您可以通過這種方式使用鹽。這將是一種哈希拉伸過程。通常,您通過重複執行數千次算法來擴展哈希,這會使攻擊者和用戶的速度降低1000倍,但用戶通常不介意這種速度降低。以這種方式使用鹽會產生哈希擴展算法的效果,因為必須對許多未知的哈希重複該算法。

但是,這是一種非常不尋常的方法。傳統的加鹽方法可以使鹽達到更好的效果(使鹽變得沒有人可以預先計算出密碼表)。傳統的進行哈希擴展的方法做的哈希擴展應該做的要好得多(這樣做使攻擊者需要更長的時間來計算密碼)。以這種方式使用鹽有點像將它們兩者融合在一起。結果有點類似,但較醜陋的技術混搭,更簡潔的方法在兩種解決方案上都

supercat
2016-07-15 20:52:19 UTC
view on stackexchange narkive permalink

我不是從蠻橫的角度考慮鹽,而是從說不可能通過查看密碼來告訴任何有關密碼的信息,包括密碼與其他密碼的關係。如果系統不加鹽,則查看兩個用戶的哈希密碼將表明他們的真實密碼是否匹配。如果系統僅使用用戶名進行鹽醃,而沒有使用隨機,特定時間或特定於系統的鹽,那麼在使用相同方法的兩台計算機上查看用戶的哈希密碼將表明兩台計算機上的用戶密碼是否匹配。如果系統使用系統ID和用戶名進行了加鹽處理,但沒有隨機性或特定於時間的設置,則可以由同一用戶訪問兩個不同密碼哈希的人可以判斷關聯的密碼是否匹配。

隨機加鹽是為了使即使使用相同密碼的兩個哈希都不會匹配,即使它們涉及同一系統上的同一用戶。如果登錄嘗試強行使用鹽,雖然可以在不存儲鹽的情況下達到類似的效果,但這種方法將限製鹽的實際使用長度,從而增加在兩種情況下使用密碼的可能性。相同的鹽,因此可以識別為匹配鹽。

Jason Goemaat
2016-07-18 07:24:21 UTC
view on stackexchange narkive permalink

加鹽有什麼作用?攻擊者已經預先計算了密碼哈希值的數據庫,包括普通密碼和非普通密碼。如果他們捕獲了您的數據庫並為每個用戶提供了密碼的哈希值,則很容易對照這些值檢查哈希值而無需添加鹽。

使用隨機鹽和密碼一起存儲的鹽,此瘋狂快速方法不再可行。但是,如果攻擊者既有鹽又有哈希,那麼仍然可以對弱密碼使用字典攻擊,對短密碼使用暴力破解。攻擊者所需要做的就是使用鹽,然後通過字典或蠻力攻擊嘗試使用不同的密碼。

現在,讓我們說說更改密碼時,您可以使用隨機的12位值對它進行散列不能和鹽一起儲存。然後,每次您檢查密碼時,都必須嘗試所有4096個值。在我的計算機上,這大約需要3.5毫秒,因此每秒可以檢查284個密碼。有人登錄時,服務器上的CPU使用率要高一些,但是對於嘗試字典或蠻力攻擊的人來說,即使他們有哈希值和鹽,您的工作也變得更加困難。

如果他們*沒有*哈希和鹽,您會不會使他們的工作容易得多?從現在開始,如果我僅發送一個值,則服務器會檢查4096個值,從而產生更多的誤報。這就是我的教授使用的理由,但對我而言似乎並不是很有用,所以我希望看到有人在實際代碼中實際使用此方法。
如果他們沒有哈希,那就沒有意義了嗎?鹽醃可以防止有哈希的人。如果使用12位數字變得很流行,則攻擊者可能會為這些數字中的每個數字以及常見/不常見的密碼創建帶有預先計算的哈希值的數據庫,以使他們的工作更輕鬆。即使您生成了4096個隨機鹽,而不是簡單地使用它們來代替簡單的12位數字,也將使它們只關註一個鹽值,如果您擁有數百萬個鹽,則可能會損害很多用戶。
是的,加鹽可以防止有哈希的人。通常,它不會使您*更容易*遭受沒有哈希的人的攻擊,但是使用此變體可以做到。
它如何使您*更多*變得脆弱?
因為如果您將一個密碼發送到服務器,則它需要使用所有4096種可能的鹽檢查該密碼,從而為您帶來更高的誤報率。
聽起來您正在談論使用隨機密碼的哈希算法中的衝突。如果您具有256位哈希,那麼在嘗試產生衝突時,這4096次嘗試幾乎毫無意義。擁有哈希值時可以蠻力使用_的原因是,您可以每秒在本地計算機上運行數百萬或數十億張支票。如果您的站點允許人們嘗試數百萬個密碼而不將其鎖定,則(A)您做錯了,(B)他們必須與您的服務器建立快速連接,並且(C)您應注意服務器的CPU正在釘住。
Kaz
2016-07-16 04:08:03 UTC
view on stackexchange narkive permalink

不存儲鹽的受控位數似乎有一些好處,該鹽是獨立配置的,並且與鹽的大小無關。

假設我們有32位鹽。我們可以選擇僅存儲22位,並在進行身份驗證時對其餘10位進行蠻力測試。這樣做的效果似乎是將更多回合添加到哈希函數中。合法身份認證的影響並不多,但是足以增加暴力破解的難度。

明年,計算機將變得更快。因此,我們瀏覽了密碼數據庫,並從每種鹽中剔除了一點:現在我們只存儲21位,並且必須通過11蠻力。

這就像我們將哈希強度加倍一樣,但是沒有替換算法的中斷以及使用戶重新哈希密碼(這取決於常規的密碼到期策略)。

這種“漸進式鹽丟棄”方法可以延長哈希函數的使用壽命。

但是,這些方法將合法身份驗證和蠻力攻擊減慢了相等的速度,因此充其量只能提供較小的安全層。我們的重點應該放在改進上,這些改進只會給合法使用增加恆定的額外時間,同時會增加破解難度。當然,具有此屬性的改進是增加了密碼短語中的熵!密碼中每增加一點熵,都會給合法用戶增加一定的成本,但會使暴力破解的工作量增加一倍。長度為N的密碼使用O(N)進行哈希(和鍵入),但使用O(2 ** N)進行暴力破解。在密碼中添加12位熵會掩蓋12位鹽。

“這種“漸進式鹽去除”方法可以延長哈希函數的使用壽命。”有一些哈希函數具有可配置的哈希大小(一個示例是Keccak),對我來說,將它們用作KDF的基礎原語似乎是一個更好的主意。您仍然可以使用此技術來延長未更新的密碼哈希的使用壽命(通過更新,新的哈希將具有最近配置的哈希大小),但這是否是一個好主意也值得商question。您將在每次登錄時看到用戶的純密碼(例如SRP除外),因此您可以更新哈希。
@Rhymoid您需要對密碼數據庫條目具有寫權限,才能在身份驗證時(系統短暫知道密碼時)更新哈希。例如,在經典的Unix上,每個人都可以閱讀/ etc / passwd並使用哈希進行身份驗證,但是只有setuid實用程序(如/ bin / passwd)可以更新它們。(通常,我們可以設想一個系統,在該系統中,更新身份驗證數據庫條目是與使用它進行身份驗證不同的特權,即使兩者都是僅授予某些程序的特殊特權。)
coteyr
2016-07-21 18:54:13 UTC
view on stackexchange narkive permalink

在野外,我們有一個users表。用戶表通常是

  ID |用戶名|鹽|加密密碼| horridly_insecure_reset_key ================================================= ======================== 1 | user1 | foo | 09b6d39aa22fcb8698687e1af09a3af9 | NULL2 | user2 |酒吧6c07c60f4b02c644ea1037575eb40005 | NULL3 | user3 | baz | 09b6d39aa22fcb8698687e1af09a3af9 |重置 

然後,身份驗證方法將類似於

  def authenticate(用戶,密碼)u = User.find(user:user)返回u。 crypto_password == crypto(password + u.salt)end  

通過為每個用戶加鹽,它可以確保即使知道user1的密碼,您也無法弄清楚user2的密碼或沒有鹽的用戶3。

您還可以通過設置一組加密密碼並嘗試一些加密密碼來確保您不會發現問題。

本質上,通過這種方式,每次針對用戶必須從頭開始。

即使攻擊者擁有用戶和鹽的列表,他們仍然需要對每個用戶進行破解,以查看他們是否具有密碼匹配項。如果您有一大堆鹽或一種鹽,我可以知道user1的密碼是password,然後只需找到所有匹配的加密密碼即可。因此,這種方式至少會使它們的速度降低一點。

現在,當我們查看鹽時,我們希望減少鹽的重複使用。兩種相同的鹽將使攻擊者更容易使用。如果兩個人共享相同的密碼和相同的密碼,則破壞一個用戶將破壞另一個用戶。

所以可以說我們只使用這三種鹽。我們有3000個用戶。也就是說,有1000人食用相同的鹽分。如果其中有1%的密碼為“ password”,那麼這些人可以同時被全部破解。一次有10個帳戶被黑客入侵。因為我們知道這三種鹽。這是一次非常容易的工作,一次可以讓30個人受到攻擊。

現在,如果每種鹽都是唯一的。而且我們知道user1的密碼是password,這對您沒有任何好處。您仍然只破解了1個用戶。您仍然必須為所有其他2999個用戶執行“密碼+鹽=加密密碼”。

一個非常重要的說明。

默默無聞的安全性不是安全性。這並不意味著您應該在Google上發布用戶表,因為這很愚蠢。但是,在評估安全性時,您應該假設攻擊者擁有一切。您不能說:“但是他們不知道應用程序鹽,因為他們沒有源代碼”。因為他們可以。並不是說放棄您的鹽分,而是意味著它不是真正的安全性。假設他們具有用戶名和密碼,然後嘗試使他們更難於獲取密碼。

重要提示

此處使用的代碼和表大約是實際使用的9000倍。密碼未加密,鹽太短,方法有點簡單,簡而言之,在生產中做這樣的事情並不應該被認為是安全的。我選擇這些原因僅僅是為了演示,而不是因為它們是安全的。



該問答將自動從英語翻譯而來。原始內容可在stackexchange上找到,我們感謝它分發的cc by-sa 3.0許可。
Loading...