題:
密碼哈希:加鹽+胡椒粉還是鹽足夠?
Jacco
2011-04-22 14:53:02 UTC
view on stackexchange narkive permalink

請注意::我知道安全密碼存儲哈希的正確方法是scrypt或bcrypt。這個問題不是在實際軟件中實現的,而是我自己的理解。

相關


背景
據我所知,推薦/批准的用於存儲密碼驗證程序的方法是存儲:

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

其中:

  • hash()是一種密碼哈希算法
  • $ salt 是隨機,均勻分佈的高熵值
  • $ password 是用戶輸入的密碼

有人建議將密鑰添加到組合中(有時稱為 pepper )。胡椒是秘密的,高熵的,特定於系統的常數。

基本原理是,即使攻擊者掌握了密碼驗證程序,也很有可能他或她不知道胡椒價值。因此,發起成功的攻擊變得更加困難。

所以,我的問題是:
在哈希密碼提高整體安全性的同時,除了鹽之外,還添加了Pepper值嗎?

還是基於錯誤的假設而提高了安全性?

快速更新
我知道 $ salt salt>的用途code>(我在StackOverflow上寫了一個長答案),另外的 $ pepper not 不能改善鹽的作用。 br>問題是,除了鹽之外, $ pepper 是否會添加任何其他安全性嗎?

您可以為哈希加鹽,以避免它們被彩虹表破解。然後,三元組並不需要太多的額外的常量來添加。
與http://security.stackexchange.com/questions/211/password-hashing相關但不完全相同
就像@WzeberaFFS所說的那樣,這樣“發布”鹽就不會產生額外的加密強度。我以為您在問為什麼/ etc / passwd之類的哈希為何採用$ 1 $ saltsalt $ realhashhereblahblah格式,對嗎?如果是,則驗證者可以使用密碼,向其添加可見的鹽,然後對其進行哈希處理。如果看不到鹽,您將永遠無法重新創建哈希。
@Marcin,不,我是問問題中到底寫了什麼。我對鹽的用途不感興趣。我正在尋找通過向哈希添加秘密密鑰來提高安全性的方法。
那麼答案很簡單:“額外”鹽不會使任何問題變得更好。如果人們開始為小鹽預計算哈希表,則延長適當的鹽的長度會更好。
如果我理解正確,並且在我所鏈接的《問答》中對此進行了討論,那麼花椒可以“ ...通過將一部分拼圖存儲在其他位置來幫助緩解某些折衷方案(例如,數據庫備份丟失)”(@RoryMccune)。如果您構造了足夠大的彩虹桌,也可以將您的哈希與其他人區分開...
這個問題專門問胡椒。有關更廣泛的信息,請參閱IT安全性StackExchange上其他地方的更完整討論,其中涉及[密碼哈希]的更一般主題(http://security.stackexchange.com/questions/211/how-to-securely-hash-passwords)
大量反對使用胡椒的論點:https://stackoverflow.com/a/16896216/4031815
@commonSenseCode,是的,可以反對使用胡椒粉。但是,有很多爭論並不能自動提出更好的觀點。以胡椒為例,當在正確的環境中使用時,到現在為止,它已被廣泛接受為提高安全性的方法。自2017年以來,甚至NIST也開始推薦它。
[Dropbox博客](https://blogs.dropbox.com/tech/2016/09/how-dropbox-securely-stores-your-passwords/)他們添加了胡椒粉。[Filippo Valsorda早在2014年就寫過博客](https://blog.filippo.io/salt-and-pepper/)他認為辣椒是個好主意-他是著名的安全專家,目前正在研究Google的密碼學團隊。如果您不接受近200票贊成,請從他們那裡接受。
在哈希表外加鹽的目的是什麼?
我們根據環境使用不同的胡椒粉(並“安全地存儲”)。這也確保了散列不能在整個環境中“轉移”,類似於使用特定於環境的密鑰進行加密。(也有一個類似的用途適用於基於密鑰的加密:其意圖是:還需要解決另外一個難題,這使得在環境之間實現“數據傳輸”變得更加困難。)
七 答案:
Jesper M
2011-04-23 13:36:23 UTC
view on stackexchange narkive permalink

在某些情況下,花椒會有所幫助。

作為一個典型示例​​,假設您正在構建Web應用程序。 Web應用程序代碼(在某些Web應用程序框架中運行,ASP.NET MVC,Python上的金字塔無關緊要)和用於存儲的SQL數據庫。 Web應用程序和SQL DB 運行在不同的物理服務器上

最常見的數據庫攻擊是成功的SQL注入攻擊。這種攻擊不一定能訪問您的Web應用程序代碼,因為Web應用程序在其他服務器&用戶ID上運行。

您需要安全地將密碼存儲在數據庫中 ,並提出以下形式的內容:

  $ hashed_pa​​ssword = hash($ salt。$ password) 

其中 $ salt $ hashed_pa​​ssword 表示形式以及為每個新密碼或更改的密碼隨機選擇的 一起存儲在數據庫中。每個密碼哈希方案最重要的方面最重要的方面是 hash 是一種 slow 加密安全哈希函數,請參見 https://security.stackexchange .com / a / 31846/10727了解更多背景知識。

然後問題是,假設為常量添加一個恆定值幾乎是零的努力。應用程序代碼,並且該應用程序代碼通常不會被破壞進行SQL注入攻擊,那麼下面的內容是否比上面的要好?

  $ hashed_pa​​ssword = hash($ pepper。 $鹽。 $ password) 

,其中 $ salt 以明文形式存儲在數據庫中,而 $ pepper 是以明文形式存儲在數據庫中的常量。應用程序代碼(如果代碼在多個服務器上使用或源是公共的,則為配置)。

添加此 $ pepper 很容易-您只是在代碼中創建一個常量,輸入一個較大的加密安全隨機值(例如,來自/ dev / urandom hex或base64編碼的32byte)並在密碼哈希函數中使用該常量。如果您已有用戶,則需要一種遷移策略,例如,在下次登錄時重新哈希密碼,並在哈希旁邊存儲密碼哈希策略的版本號。

答案:

使用 $ pepper 確實增加了密碼散列的強度,如果數據庫的損害並不意味著的應用程序。在不了解Pepper的情況下,密碼仍然完全安全。由於密碼特定的鹽,您甚至無法找出數據庫中的兩個密碼是否相同。

原因是 hash($ pepper。$ salt。$ password) 使用 $ pepper 作為鍵並輸入 $ salt。$ password 作為輸入有效地構建偽隨機函數(對於理智的 hash 候選對象,例如帶有SHA *,bcrypt或scrypt的PBKDF2)。偽隨機函數的兩個保證是,您不能從秘密密鑰下的輸出推論輸入,也不能在不知道密鑰的情況下從輸入推論輸出。這聽起來很像哈希函數的單向屬性,但是不同之處在於,使用像密碼這樣的低熵值,您可以有效地枚舉所有可能的值,並在公共哈希函數下計算圖像,從而找到其值圖像與原圖像匹配。使用偽隨機函數,沒有鍵就無法做到這一點(即沒有胡椒),因為沒有鍵就無法計算單個值的圖像。

如果可以長時間訪問數據庫,並且仍然可以從外部正常使用該應用程序,則 $ salt 在此設置中的重要作用將發揮作用。如果沒有 $ salt ,則可以將您控制的帳戶的密碼設置為已知值 $ passwordKnown ,然後將哈希值與未知密碼的密碼進行比較 $ passwordSecret 。作為 hash($ pepper。$ passwordKnown)== hash($ pepper。$ passwordSecret)的情況,當且僅當 $ passwordKnown == $ passwordSecret 時,您才可以將未知密碼與任何選擇的值(出於技術上的考慮,我假設哈希函數具有抗碰撞性)。但是如果加上鹽,則當且僅當 $ salt1時,您會得到 hash($ pepper。$ salt1。$ passwordKnown)== hash($ pepper。$ salt2。$ passwordSecret)。 $ passwordKnown == $ salt2。分別為 $ passwordKnown $ passwordSecret code分別隨機選擇了$ passwordSecret $ salt1 $ salt2 。 >鹽將永遠不會相同(假設隨機數足夠大,例如256位),因此您將無法再將密碼進行相互比較。

嗯,編輯刪除了@Jesper Mortensen撰寫的答案中存在的大部分不確定性。也許應將編輯回滾並移至單獨的答案?
這裡的論點很不錯,我傾向於同意。但是,如果可以避免,請不要在代碼中放入常量,而應將其設置為某種配置變量(不存儲在數據庫中,也不存儲在代碼中)。
@Jacco:我同意,隨著所做編輯的完成,此答案的語調也有所變化。但是,接下來,看看誰進行編輯,我現在很自在(在其範圍內)這個答案是正確的,因此我很樂意將其保留為現在。 :-)
我同意以下說法:**添加恆定值幾乎是零的工作**。的確如此,儘管它不如添加密碼那麼重要,但我認為沒有理由排除某種形式的胡椒來提供應用程序代碼級保護。
@frankodwyer, **您甚至可以同時擁有兩者。** Web服務器上代碼中的常量,以及另一台服務器上“ config”實體中的另一個常量。
如果您為另一個RNG保存了一個byte [],然後又加上了鹽,又添加了另一個數據塊怎麼辦?那還可以用作“變辣椒”嗎?
@frankodwyer將胡椒放在配置中的安全優勢是什麼?配置通常存儲在相同的源代碼控制存儲庫中,以純文本格式與二進製文件一起部署,並加載到內存中。我想如果您想更改Pepper配置更加容易,但是無論如何您都必須擔心遷移路徑,這實際上是工程問題,而不是安全問題。
話雖如此,這裡有一個“安全配置”的概念,例如Azure Key Vault(使用HSM)。您可以將您的秘密放在那裡,並在運行時安全地獲取它,甚至可以將其作為“ SecureString”保留在內存中。這無疑將為潛在的攻擊者帶來嚴重的障礙。
關於比較“ passwordKnown”散列,我懷疑這是否是一種可行的方法,因為您可以在Web應用程序中更改密碼的速率(大概使用面向用戶的界面,即使您以某種方式編寫腳本以使用基礎HTTP / API也是如此)對於您實際發起任何攻擊可能太慢了。
將鹽存儲在數據庫中有什麼好處?例如,Drupal系統僅將鹽存儲在文件系統中。
@CapiEtheriel只要您在每次對新密碼進行哈希處理時都生成新鹽,並將其存儲在文件系統中,最終結果將是相同的(文件系統解決方案非常笨拙)。但這聽起來像是在誤解鹽的目標-通過使其變慢來減緩密碼破解,以便每個密碼都必須分別處理。兩個不同用戶的相同密碼將有所不同,並且由於鹽的差異,您在一個用戶中發現的任何哈希值對於另一個用戶都將無關緊要,因此鹽可以是“公開的”而不會帶來安全風險。
Thomas Pornin
2011-04-22 19:53:35 UTC
view on stackexchange narkive permalink

(注意:使用鹽僅是工作的一半;您還需要使散列函數變慢-因此攻擊單個低熵密碼仍然很困難。緩慢性通常是通過多次迭代或散列來實現的鹽和密碼的10000個副本的串聯。)

“胡椒粉”的作用是將哈希值轉換為 MAC。用散列函數製作一個好的,安全的MAC並不容易,因此,您最好使用 HMAC而不是自製的結構(將其用作抗碰撞散列函數的理論方法是

使用MAC,您可以 在以下意義上獲得一定的安全性:可能,攻擊者對數據庫的讀取訪問可能不再是一種安全。真正的問題。 MAC密鑰(“ pepper”)可以集中機密性需求。但是,這依賴於MAC也是一種單向函數,這是您可以從許多MAC構造(包括HMAC)中獲得的屬性,但是從密碼上來說,並不能真正保證它的存在(有些微妙之處)。

“ pepper”意味著您需要管理一個密鑰,包括以不會重啟的方式進行的安全存儲。密鑰很小並且適合RAM,但是由於存儲要求,目前尚不清楚它是否真正提高了安全性。可以讀取整個數據庫的攻擊者通常還可以讀取整個硬盤,包括任何“受保護”的文件。較小的按鍵可能允許某些高級設置,例如密鑰存儲在智能卡上,該智能卡在引導時使用,但之後未保持連接狀態。綜上所述,加薪是否值得付出的努力完全取決於具體情況,總的來說,我建議不要這樣做,以免增加複雜性。

我正在嘗試將腦筋圍繞“添加哈希將其轉換為MAC”。我是否理解正確,即通過在哈希算法中添加一個常量值(以及密碼和鹽),原語的更改會影響結果的強度?而且,如果知道密鑰,整個方案可能不太安全?
@Jacco:如果哈希函數很好,那麼不能,您不會通過添加已知的前綴或後綴以任何方式削弱它。但是,具有良好的哈希功能並不完全等同於具有良好的MAC(區別很小,但卻是真實的),因此需要遵循經過深入研究的構造,例如HMAC。對於一本好書,您可以嘗試《應用密碼學手冊》(http://www.cacr.math.uwaterloo.ca/hac/)(與Schneier的“ Applied Cryptography”不是同一本書)。
@Thomas Pornin:請在下面查看我的答案-我不確定我們是否在談論同一件事。如果是的話,那麼我在下面使用Webapp開發人員更常用的詞,因此您對我所描述的內容的評論將很有價值。
@Jesper:我們正在談論同一件事,但觀點截然不同。 “ pepper”僅在攻擊者不知道的情況下才能提高安全性-是否真的是不容易猜測的,尤其是在Webapp和數據庫位於不同機器上的設置中。 Pepper本身不會降低安全性,只是它增加了安裝的複雜性(攻擊者必須不知道的值是密鑰,而密鑰管理是不直接的)。同樣,使用秘密胡椒,安全性的提高取決於該構造是否為良好的MAC。
“ _“ pepper”意味著您需要管理一個密鑰,包括以一種不會重啟的方式來保護安全存儲。_”如果可以,為什麼不對密碼數據庫進行加密?
@curiousguy:很好,可以。有些人可能將哈希視為附加的安全層:即使攻擊者獲得了“ pepper”,他仍然無法立即恢復密碼(他可以進行離線字典攻擊,但這並不像擁有解密密碼列表那樣容易)。
-1表示“可以讀取整個數據庫的攻擊者通常也可以讀取整個硬盤”。顯然,您不是滲透測試人員,請不要做這樣的假設。
很好,Rook指出了Thomas的評論中的缺陷(感謝@Rook);仍然,我贊成這個答案,因為總的想法是有道理的,那就是重要的事情:我同意複雜性是安全的大敵。
@Lex, **不必要**複雜性是安全的大敵。安全性本身就很複雜。
@rook,最好指出答案中的缺陷,而不是攻擊作者的憑據,因為指出該缺陷會增加其他用戶可以用來判斷答案的信息。我將在這裡進行操作。數據庫憑據通常等於整個操作系統訪問權限並不正確。數據庫服務器經常與運行它們的應用程序分開,後者通過網絡連接。或者,即使數據庫用戶無法脫離其沙箱,數據庫軟件中的缺陷也可能導致對數據庫的完全訪問。
“您需要管理的密鑰”可能只是我應用中的一行代碼(例如const key =“ 76fc67a8-dde0-4f49-9e5e-84fb186b97b9”`),所以我不明白為什麼不這樣做。正如其他人提到的那樣,對我的數據庫的讀訪問權限可能與對我的二進製文件/源代碼的訪問權限相去甚遠。
也可以將密鑰添加到一個人的基於HSM的秘密保險庫(無論如何,他必須管理和檢索秘密),例如Azure Key Vault。然後,即使攻擊者檢索了代碼和二進製文件,他也沒有獲得秘密。甚至可以更進一步,將密鑰安全地存儲在內存中(例如.NET的“ SecureString”),在這種情況下,即使訪問服務器的內存也可能不容易導緻密鑰洩漏。增加的複雜度將非常低。
martinstoeckli
2012-11-02 20:52:40 UTC
view on stackexchange narkive permalink

我想指出胡椒的真正作用。

胡椒什麼時候提供幫助?

正如其他人已經指出的那樣,加入胡椒只是一個優勢。 ,只要攻擊者可以訪問數據庫中的哈希值,但無法控制服務器,因此不知道Pepper 。這對於SQL注入來說是典型的,因為它很容易做到,可能是更常用的攻擊之一。

Pepper有什麼改進?

  $ hashValue = bcrypt('12345',$ cost,$ salt);  

即使正確使用了慢速鍵派生功能,也可以通過字典攻擊輕鬆獲得此密碼。將最常用的密碼放入字典中,並使用此弱密碼進行暴力破解。

  $ hashValue = bcrypt('12345anm8e3M-83 * 2cQ1mlZaU',$ cost,$ salt);  

使用Pepper,弱密碼的長度會增加,現在包含特殊字符,更重要的是,您不會在任何詞典中找到它。因此,只要Pepper保持秘密,它就會防止字典攻擊,在這種情況下,它可以保護弱密碼。

編輯:

有與使用服務器端密鑰相比,這是一種更好的方法。使用胡椒,攻擊者必須在服務器上獲得其他特權才能獲取密鑰。通過首先計算哈希,然後使用服務器端密鑰對哈希進行加密(雙向加密),我們可以獲得相同的優勢。

  $ hash = bcrypt($ passwort,$ salt); $ encryptedHash = crypto($ hash,$ serverSideKey);  
  $ hash = bcrypt($ passwort,$ salt);  en>代碼> 
我建議bcrypt(hash_mac('sha256',$ password,$ pepper),$ salt)
@Jacco-剛剛添加了一個使用hmac的示例。
我不確定您的示例使用哪種語言,但是如果它與語言無關,則將更加清楚
@Jacco-它是PHP,但是函數`bcrypt`是虛構的,因為PHP本身還沒有提供這樣的功能(在5.5之前),但是函數`hash_hmac`存在。我試圖編輯答案,所以所有令人困惑的部分都被刪除了,您認為我還能做些什麼呢?
nealmcb
2011-05-10 10:21:24 UTC
view on stackexchange narkive permalink

關於Unix密碼鹽化和迭代發明的論文(密碼安全性:案例歷史,Morris & Thompson,1978)也描述了胡椒的等效性:

用戶密碼的前八個字符用作DES的密鑰;然後使用該算法對常量進行加密。儘管此常數目前為零,但可以輕鬆訪問,並且可以依賴於安裝。

我還沒有聽說過使用它。還有其他人嗎?

我認為所有現代發行版都使用基於散列函數(而不是像DES這樣的加密函數)的東西,因此該功能不再可用。
eckes
2017-05-06 23:08:35 UTC
view on stackexchange narkive permalink

就像BTW一樣,新的NIST數字身份指南(草案)也強烈建議也使用Pepper:

https://pages.nist.gov/800-63-3/ sp800-63b.html#sec5

5.1.1.2記憶秘密驗證者:

...密鑰哈希函數(例如,HMAC [FIPS198-1] ]),並且密鑰應與散列的身份驗證器分開存儲(例如,在硬件安全模塊中),應進一步抵抗針對所存儲的散列的身份驗證器的字典攻擊。

哇,我多年來一直提倡使用胡椒,但人們很少出於無故的理由實施胡椒。我不知道NIST現在也推薦它!感謝您的答复,這應該更高。
Alex R
2013-08-31 11:20:25 UTC
view on stackexchange narkive permalink

請考慮以下情形:

我即將使用SQL注入方法闖入網站X,以檢索用戶列表以及其密碼哈希和鹽。假設網站X也在使用全局Pepper。

我要做的就是在網站X上用SQL注入之前我已知的用戶名和密碼註冊一個用戶。然後,對於數據庫中的特定記錄,我將知道密碼哈希,純文本密碼,salt(以純文本存儲),而根據此一條記錄來破解全局胡椒對我來說在計算上是微不足道的。

所以,實際上,胡椒將是使攻擊者在瑣碎的開銷時間內減速的一種方法。他們不必像預期那樣強行使用密碼+鹽+胡椒粉。

上面是選擇明文攻擊的一種形式。只要攻擊者知道算法(hash()),輸出($ hashed_pa​​ssword)以及所有輸入之一(“常量” $ salt & $ password和“變量” $ pepper),他們就可以“求解x就像線性代數方程式(h = s + p + x == hsp = x),但當然是蠻力。使Pepper長度超過bcrypt的限制56字節(448位),增加了時間成本,與bcrypt一樣好,但仍不如scrypt好。因此,只要胡椒足夠長,它就會有所改善。

如果Pepper是128位隨機值怎麼辦?根據salt和明文密碼值破解它仍然微不足道嗎?鹽和胡椒粉值之所以有用的原因是,您可以輕鬆地使其足夠長(128位),而不必記住它,這就是為什麼通過蠻力破解它從來都不是一件容易的事。
如果Pepper是128位隨機值,那麼破解當然也不是一件容易的事。但是,您必須記住以下幾點:-將此值添加到**每次單次驗證**的哈希函數的開銷上-胡椒是全局的,只需用蠻力破解一次,而不是為每個記錄破解一次-比起胡椒粉,增加鹽的長度要好得多
任何甚至部分合適的哈希函數(如bcrypt,腳本或什至某些sha的多次迭代)的成本也不取決於密鑰的長度,因此這是錯誤的。如果正確選擇了哈希函數,而不僅僅是使用“ sha256”的單次迭代,那麼花椒只需要將初始密碼提升為50位熵,就可以使它成為幾十年甚至幾十年的防彈技術。當然,就像@void_in所說的那樣,我們將其提升到128位或256位,只是因為我們可以。
Brian Sparks
2014-09-07 23:04:07 UTC
view on stackexchange narkive permalink

對服務器如何隱藏全局Pepper常量不是很熟悉,但我的看法是滲透到服務器中的黑客遲早會弄清楚如何獲取Pepper的價值。安全將需要特殊的硬件。一種方法是使用服務器中安裝的FPGA板。 FPGA將包含用於執行哈希的代碼,包括Pepper值,並且所有哈希計算都在FPGA內部進行。使用FPGA,編程可以是一種單向功能。可以編程胡椒,但是沒有指令可以發送以將其讀出。胡椒粉將存儲在鎖在保險箱中的紙上。如果Pepper是隨機生成的128多個位,將沒有確定它的實用方法。
不確定會增加服務器硬件成本,因此不實用。

有可用的加密模塊執行類似的操作-用於存儲+驗證密碼和/或密鑰的單向設備。


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