題:
如何儲存鹽?
George
2012-07-20 11:28:12 UTC
view on stackexchange narkive permalink

如果希望安全地存儲用戶密碼,則至少需要執行以下操作:

  $ pwd = hash(hash($ password)+ salt)  

然後,將 $ pwd 而不是真實密碼存儲在系統中。我曾見過某些情況,其中 $ pwd 包含 salt 本身。

我想知道鹽是否應該單獨存放,或者是否可以攻擊者同時獲取哈希值和鹽。為什麼?

好吧,鹽要考慮的一件事。如果您確實設法將其保密,並且密碼哈希被洩露,那麼即使有10,000張顯卡被強行使用,也完全不可能(可能)恢復密碼。
@Earlz鹽的用途不是“ **”,而將鹽隱藏起來幾乎是不可能的!
@Polynomial好,需要考慮的事情。我有一個身份驗證系統,該系統對每個密碼使用兩種鹽,一種鹽隨機生成並存儲在數據庫中,另一種對網站是全局的並存儲在代碼中。我的目標是做到這一點,以便即使數據庫洩漏,也仍然無法偽造登錄cookie或暴力破解密碼。
@Earlz第二種鹽稱為[胡椒](http://security.stackexchange.com/questions/3272/password-hashing-add-salt-pepper-or-is-salt-enough),可以保護您免受攻擊者的攻擊只能訪問數據庫。它很有用,但是由於您使用的是參數化查詢(*正在*正在使用它們,對嗎?)SQL注入不是問題,因此攻擊者模型的可能性大大降低。
嘿,我不知道這個名字叫@Polynomial。而且我很確定我的數據庫是安全的,但以防萬一不是。 (MongoDB)。我認為這不會造成傷害,並且實施起來並不難
原諒我的無知,但真的有必要在加鹽之前對密碼_before_進行哈希處理嗎?如果您擁有良好的哈希算法,那麼就不應該有所作為,對吧?
$ pwd = hash(hash($ password)+ username)呢?
@X-Zero應該沒有任何區別,使用自適應KDF時,它會使事情更加尷尬。
@SilverViper這是一個壞主意。它使攻擊者大吃一驚,使他們可以在公開破壞數據庫之前提前計算出彩虹表。在這種情況下,攻擊者可以在攻擊後立即登錄,而您沒有時間做出反應。有關此問題的更詳細說明,請參見我的答案。
+1使用鹽,這比大型網站通常要多。
@JonasWielicki是。有些甚至以明文形式存儲。有關示例,請參見[純文本違規者](http://plaintextoffenders.com/)。樂購是另一家沒有在那上市的大公司。
你為什麼要儲存鹽?如果您可以通過某種方式使用憑據來計算它,例如$ salt = base64_encode($ username。$ password);則不必存儲它,並且如果用戶名和密碼正確,它將匹配鹽也一樣。
@matejkramny這完全等同於僅使用用戶名作為鹽,並且出於相同的原因也是很糟糕的:如果攻擊者知道他們想要破解的用戶名,則他們可以預先計算該用戶名的哈希值。在密碼中包含密碼不會改變任何事情。為了阻止它們預先計算哈希,應將鹽存儲在數據庫中,這樣它們就無法在自己獲取哈希之前獲取它,這意味著*在*破壞數據庫之後*,它們需要大量時間才能破壞哈希。讓您有機會在訪問密碼之前更改密碼。
//,您使用的是什麼容器?您使用的是碘化還是非碘化?可能會沾上有毒的鹽,因此請避免使用金屬容器,因為鹽會從金屬中浸出金屬和/或元素。好吧,不管怎麼說,您不必使用食物保護劑,因為即使暴露在空氣中,鹽也不會腐爛。對於大量,我建議將鹽鏟入重型加侖大小的塑料袋中。然後,您可以將袋子放在食品級5加侖的水桶中。對於所有在那裡準備的人,可以在需要時用作易貨物品。
//,https://selfreliantschool.com/how-and-why-to-store-salt
六 答案:
Polynomial
2012-07-20 19:23:55 UTC
view on stackexchange narkive permalink

TL; DR-您可以以純​​文本格式存儲鹽,而無需進行任何形式的混淆或加密,但不要將其分發給任何需要的人。


我們使用鹽的原因是為了阻止計算前攻擊,例如彩虹表。這些攻擊涉及創建哈希及其明文的數據庫,以便可以搜索哈希並立即將其反轉為明文。

例如*:

  86f7e437faa5a7fce15d1ddcb9eaeaea377667b8 ae9d71f5ee7c92d6dc9e92ffdad17b8bd49418f98 b84a516841ba77a5b4648de2cd0dfcb30ea46dbb4ç... 948291f2d6da8e32b007d5270a0a5d094a455a02 ZZZZZX151bfc7ba4995bfa22c723ebe7921b6ddc6961bc ZZZZZY18f30f1ba4c62e2b460e693306b39a0de27d747c ZZZZZZ 代碼> 

大多數表還包括常見密碼的列表:

  5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8 passworde38ad214943daad1d64c102faec29de4afe9da3d password1b7a875fc1ea228b9061041b7cec4bd3c52ab3ce3 letmein5cec175b165e3d5e62c9e13ce848ef6feac81bff qwerty123 代碼> 

**這裡我以SHA-1為例,但是稍後我將解釋為什麼這是個壞主意。 sup>

所以,如果我的密碼哈希為 9272d183efd235a6803f595e19616c348c275055 ,則在數據庫中搜索它非常容易並發現明文是 bacon4 。因此,您無需花幾個小時來破解哈希(好的,在這種情況下,在體面的 GPU上要花幾分鐘,但是我們稍後再討論),您可以立即獲得結果。

顯然,這不利於安全!所以,我們用鹽。鹽是隨每個密碼存儲的隨機唯一令牌。假設鹽是 5aP3v * 4!1bN<x4i&3 ,哈希是 9537340ced96de413e8534b542f38089c65edff3 。現在,您的密碼數據庫已無用,因為沒有人擁有包含該哈希的彩虹表。為每種可能的鹽生成彩虹表在計算上是不可行的。

因此,現在我們已經迫使壞傢伙再次開始破解哈希。在這種情況下,由於我使用了錯誤的密碼,因此很容易破解,但比他能夠在十分之一秒的時間內查到密碼要好得多!

現在,由於目標鹽僅用於阻止創建預先生成的數據庫,不需要在數據庫中對其進行加密或遮蓋。您可以將其以純文本格式存儲。目的是迫使攻擊者一旦獲得數據庫就必須破解哈希,而不是只能在彩虹表中查找所有哈希。

但是,有一個警告。如果攻擊者可以在 進入您的數據庫之前悄悄訪問鹽,例如通過一些向任何需要鹽的人提供鹽的腳本,他可以像沒有鹽一樣輕鬆地為該鹽生成彩虹表。這意味著他可以默默地獲取您的管理員帳戶的費用,並生成一個漂亮的大彩虹表,然後入侵您的數據庫並立即以管理員身份登錄。這樣您就沒有時間發現發生了違規行為,也沒有時間採取行動來防止損壞,例如更改管理員密碼/鎖定特權帳戶。這並不意味著您應該掩蓋鹽或嘗試對其進行加密,而只是意味著您應該設計系統,以使鹽的唯一途徑就是闖入數據庫。

另一個要考慮的想法是辣椒。胡椒是第二種鹽,在各個密碼之間保持不變,但未存儲在數據庫中。我們可以將其實現為 H(鹽+密碼+胡椒粉) KDF(密碼+胡椒粉,鹽)以實現鍵派生功能-我們將討論那些後來。這樣的值可以存儲在代碼中。這意味著,攻擊者必須同時訪問數據庫和源代碼(在ASP.NET,CGI等情況下,則必須是webapp二進製文件),才能嘗試破解哈希。這個想法只能用於補充其他安全措施。當您擔心SQL注入攻擊(攻擊者只能訪問數據庫)時,Pepper很有用。但是隨著人們轉向參數化查詢,這種模型(慢慢地)變得不那麼普遍了。您使用參數化查詢,對不對?有人認為,胡椒粉通過遮蓋力構成安全性,因為您只是使胡椒粉變得晦澀難懂,這在一定程度上是對的,但這並不是說這個主意沒有根據。

現在我們處在一種情況下攻擊者可以在其中暴力破解每個密碼散列,但不再能夠在彩虹表中搜索所有散列並立即恢復純文本密碼。那麼,我們現在如何防止暴力攻擊?

現代圖形卡包括具有數百個內核的GPU。每個核心都非常擅長數學,但並不擅長決策。它每秒可以執行數十億次計算,但是在執行需要復雜分支的操作​​時非常糟糕。加密哈希算法適合於第一類計算。因此,可以利用諸如 OpenCL CUDA之類的框架來大規模加速哈希算法的運行。使用性能不錯的圖形卡運行 oclHashcat,您每秒可以計算出10,000,000,000個MD5哈希值。 SHA-1也不慢。那裡有專用的GPU破解設備,其中包含6個或更多的高端圖形卡,從而使MD5的破解速度超過每秒500億哈希。讓我把它放在上下文中:這樣的系統可以在不到4分鐘的時間內暴力破解8個字符的字母數字密碼。

像MD5和SHA-1這樣的哈希值太快了對於這種情況。一種解決方法是執行加密哈希算法的數千次迭代:

  hash = H(H(H(H(H(H(H(H(H(H(H( H(H(H(H(... H(密碼+鹽)+鹽)+鹽)...) 

這會減慢哈希計算的速度,但並不完美一些提倡者使用 SHA-2家庭散列,但這並不能提供更多的安全性,更可靠的方法是使用帶有工作因子的密鑰派生函數,這些函數採用密碼,鹽和工作因數。工作因數是一種根據硬件和安全要求擴展算法速度的方法:

  hash = KDF(密碼,salt,workFactor) 

兩個最受歡迎的KDF是 PBKDF2 bcrypt。 PBKDF2通過執行鍵控 HMAC(儘管它可以使用分組密碼)的迭代來工作,而bcrypt通過計算和組合來自 Blowfish分組密碼的大量密文塊來工作。兩者的工作大致相同。較新的bcrypt變種 scrypt遵循相同的原理,但是引入了內存硬操作,由於內存帶寬的原因,破解GPU和 FPGA場完全不可行限制。


更新::截至2017年1月,首選的最新哈希算法為 Argon2


希望這對您在存儲密碼時遇到的問題有一個很好的概述,並回答了有關鹽存儲的問題。我強烈建議您查看 Jacco答案底部的“感興趣的鏈接”以及以下鏈接:

+1,阿們我希望我們在哪裡能夠創建一個索引/目錄,以指向諸如此類的常見/受歡迎問題的良好答案。更重要的是,因為常見/常見問題也經常吸引不安全的答案。
前幾天,我在閱讀有關[Scrypt](http://en.wikipedia.org/wiki/Scrypt)的信息,這是一種KDF,其目標是在計算上比Bcrypt和PBKDF2更昂貴。這可能是值得考慮的另一種選擇。
@GarrettAlbright我在倒數第二段提到了scrypt。 Scrypt的唯一缺點是可用的庫不多,對此也沒有太多研究。現在我建議使用bcrypt,因為對於大多數人來說,基於FPGA的破解引擎並不是安全性問題,但是當一些密碼學家對scrypt進行仔細研究時,我很樂意告訴人們使用它。
Also have a look at https://wiki.mozilla.org/Identity/CryptoIdeas/01-PBKDF-scrypt
@Polynomial可能還會添加指向http://stackoverflow.com/questions/1645161/salt-generation-and-open-source-software/1645190#1645190的鏈接?
+1,用於鏈接到@Jacco's答案的“感興趣的鏈接”部分。
但是,如果您實施短信代碼之類的因素,那麼您甚至可以將密碼存儲在明文中。因為密碼仍然需要通過短信代碼。
@matejkramny否。主要問題是用戶將始終在其他站點上重複使用其密碼。您有責任保護提供給您的任何密碼。
重新散列密碼時總是再次添加鹽的原因是什麼?
-1
從程序員的角度來看,bcrypt也是最容易使用的。您甚至不需要自己自己添加鹽,因為加密庫會為您完成操作,因為輸出包括鹽(格式為`$ $ $ <22 character salt> <31個字符哈希>`)。因此,所有需要的信息都存儲在您可以認為是哈希的內容中。沒有比這更容易的了(儘管仍然很安全)。
只是為了強調:請確保為每個密碼使用***不同的鹽!如果為每個密碼使用相同的鹽,則蠻力算法的計算複雜度將大大降低。此外,攻擊者僅通過比較散列就可以查看哪些用戶使用相同的密碼,這可能會對跨多個帳戶重複使用密碼的用戶產生匿名性。
Bouncycastle具有scrypt實現。
真的很好的答案。但是您仍然沒有回答“我在哪裡存儲隨機鹽”的問題?您需要使用隨機鹽檢查輸入的密碼是否正確...我錯了嗎?
“這意味著攻擊者必須同時訪問數據庫和源代碼”-在最後一部分中並非如此。在許多(如果不是大多數)情況下,字符串不會被加密。黑客可以輕鬆地在十六進制編輯器中加載可執行文件,並查看大多數字符串。他們還可以單步執行彙編代碼以讀取值。在許多情況下,不需要源代碼,因此在客戶端(即桌面應用程序)存儲/計算的任何鹽和胡椒值也不是不可能的;辛苦了;)不要將它們存儲為純文本格式。混淆這些類型的字符串以使其更難查找。
@JamesWilkins是的,當我撰寫本文時,我想到的是PHP / Python Web應用程序。我將進行編輯以反映Web應用程序是.NET或CGI二進製文件的各種情況。
–1 –文本太多,並且實際上沒有回答存儲鹽的位置的問題(儘管由於文本與實際問題無關,我中途停止了閱讀)
Jacco
2012-07-20 12:37:05 UTC
view on stackexchange narkive permalink

鹽並不意味著是秘密的,相反,鹽通過確保哈希結果對於每個使用的實例都是唯一的而“起作用”。這是通過為每個計算出的哈希值選擇一個不同的隨機鹽值來完成的。

已知鹽的意圖不會受到損害;攻擊者仍然需要分別攻擊每個哈希。因此,您可以將鹽與哈希密碼一起存儲。

感興趣的鏈接
如何安全地哈希密碼?
密碼哈希添加鹽+胡椒粉還是足夠鹽?
鹽生成和開源軟件

請記住,如果鹽洩漏(例如,通過代碼中的缺陷),攻擊者可以提前為該鹽建立彩虹表。如果有人以後偷了您的哈希,這會使您很難採取預防措施,因為他們可以立即破解密碼(他們已經有了Rainbow表!)並訪問該帳戶。
@Polynomial您的觀點很不錯。也許您想寫一個涵蓋您所說內容的答案?我當然會贊成它,並且以這種方式閱讀要容易得多。
@Terry Chia:前置更為常見。
除了*散亂的,加鹽的密碼*。
那麼,@Polynomial會將鹽存儲在哪裡?看來,如果攻擊者發現了鹽就可以闖入數據庫?
lxgr
2012-07-20 12:38:24 UTC
view on stackexchange narkive permalink

可以並且應該將鹽存儲在加鹽和散列的密碼旁邊。另外,salt應該對每個密碼都是唯一的。因為只有在攻擊者獲得實際的(強化的)密碼後,鹽才會被攻擊者知道;從而使任何預先計算的攻擊都變得不可能。 (如果您不是每個密碼使用唯一的鹽,而是全局密碼,則可能仍會使用預先計算的表-儘管必須專門針對您的應用程序的鹽預先計算它們。)

當您將鹽存儲在密碼旁邊的其他位置時,您可能會獲得一些額外的安全性,但是這幾乎無法達到目的:每次您想要驗證密碼時,都需要鹽和哈希密碼,因此無論如何,它們必須非常“接近”(從豐富的意義上來說)。

Tgr
2012-07-20 22:35:16 UTC
view on stackexchange narkive permalink

單獨存儲鹽可以提供一些額外的安全性,但不能提供太多的安全性-畢竟,數據庫應該是應用程序受保護最好的地方,因此,如果攻擊者可以訪問數據庫,則他有機會訪問其他任何數據。另一方面,您需要為每個用戶使用不同的鹽,這意味著您需要大量的鹽-將其存儲在數據庫外部是不可行的。

有一種使用第二種方法的實踐。所有用戶都相同的一塊鹽(有時稱為花椒),並將其存儲在數據庫外部(可能存儲在環境變量或某種配置文件中),因此攻擊者無法通過簡單的SQL訪問它注射。這樣可以提高安全性,但是如上所述,不要期望過高,請使用bcrypt或其他慢速哈希方法來防禦鹽被盜。

user7610
2012-07-20 20:58:26 UTC
view on stackexchange narkive permalink

我想把您的注意力轉向標題為安全存儲密碼

TL; DR

的有趣文章。 >

文章中的作者解釋了鹽和胡椒。而且,他/她認為實際上您不想使用加密哈希函數來存儲密碼。哈希的兩個主要特徵是

  1. 應該是單向和。
  2. 計算起來應該便宜。
  3. ol>

    顯然,這些要求是相互矛盾的。因此做出了折衷。您不希望攻擊者能夠廉價地計算其暴力破解嘗試。因此,為了獲得更好的安全性,您實際上需要一個密鑰派生函數,它是單向的,並且計算時間較長(例如0.1 s)。

    有一些方案/實現方法,所謂的自適應密鑰派生函數,它們已經過充分研究並被認為是安全的(作者姓名三: PBKDF2 bcrypt scrypt

此時,您的答案還沒有真正買到什麼東西,因此您可能應該只在評論中鏈接該文章。不過,這是一篇不錯的文章-非常詳盡,涵蓋了所有基礎。我會保留一個書籤以供將來參考!
好文章!據我所知,PBKDF2是一個自適應密鑰派生函數,而BCrypt和SCrypt不是。它們是自適應成本哈希算法。 (差異是細微的,但卻是真實的)。
多項式:您是對的。我是如此渴望發布這篇文章(我將其保存在書籤中,並為它的時機終於到來而感到興奮),以至於我只是略過了您的答案而完全錯過了最後一段。抱歉
Andrew Smith
2012-07-21 00:41:49 UTC
view on stackexchange narkive permalink

好吧,您將鹽和哈希分別放在兩個不同的框中-我希望您理解正確的答案。並確保兩者的數量相同,例如256位Salt,256位哈希,如果使用簡單的隔離Salt服務器,則可以提高安全性。

為什麼將哈希和鹽存放在不同的地方?
參見例如http://security.stackexchange.com/a/17449/5501
-1“ 256位哈希”在這裡不會給您帶來任何好處。該算法不必太慢。分別將哈希和鹽類雜散符分開,創建一個全新的問題範圍,而是堅持採用最佳實踐。


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