security 扶輪社職業分類表 - 你在哪裡儲存你的鹽弦?





authentication hash cryptography salt (5)


我會提供一個稍微不同的看法。

我總是將混合的鹽與醃製密碼混合存儲。

例如,我將把鹽的前半部分放在密碼的鹽漬散列之前,鹽的後半部分放在密碼的鹽漬散列之後。 應用程序知道這個設計,所以可以獲取這些數據,並獲得salt和salted-password散列。

我的這種做法的基本原理是:

如果密碼/散列數據受到攻擊並落入攻擊者手中,攻擊者將無法知道鹽是從查看數據的。 這樣攻擊者實際上不能實施強力攻擊以獲得與散列相匹配的密碼,因為他不知道開始的散列並且無法知道哪部分數據是鹽的一部分,或者部分醃製密碼散列( 除非他確實知道你的應用程序的認證邏輯 )。

如果醃製密碼哈希按原樣存儲,則可以執行暴力攻擊來獲取密碼,該密碼在醃製和散列時會生成與醃製密碼哈希相同的數據。

但是,例如,即使唾沫密碼哈希按原樣存儲,但預先添加了一個隨機字節,只要攻擊者不知道該第一個字節將被丟棄,這也會增加難度的攻擊。 用於驗證用戶身份時,您的應用程序將知道丟棄數據的第一個字節。

這個結論..

1)不要以認真的形式存儲認證應用程序使用的數據。

2)如果可能的話,保持您的驗證邏輯的秘密,以增加安全性。

再往前走一步..

如果你不能保持你的應用程序的認證邏輯的秘密 - 很多人知道你的數據是如何存儲在數據庫中的。 假設你已經決定存儲與鹽一起混合的鹽醃密碼哈希,其中一些鹽預先加了鹽醃密碼哈希,而其餘的鹽加上鹽加上它。

當生成隨機鹽時,您還可以隨機決定您將在鹽漬密碼哈希之前/之後存儲的鹽的比例。

例如,您生成一個512字節的隨機鹽。 您可以將salt添加到您的密碼中,並獲取您的醃製密碼的SHA-512哈希值。 您還會生成一個隨機整數200.然後,您會存儲鹽的前200個字節,然後是鹽密碼哈希,然後是鹽的剩餘部分。

在驗證用戶的密碼輸入時,應用程序將傳遞字符串,並假定數據的前1個字節是salt的前1個字節,後跟salt-hash。 此通行證將失敗。 應用程序將繼續使用數據的前2個字節作為鹽的前2個字節,然後重複,直到使用前200個字節作為鹽的前200個字節後找到肯定結果。 如果密碼錯誤,應用程序將繼續嘗試所有排列,直到找不到任何排列。

這種方法的優點:

提高安全性 - 即使你的認證邏輯是已知的,確切的邏輯在編譯時是未知的。 即使知道確切的邏輯,實際上也不可能執行暴力攻擊。 鹽的長度增加將進一步提高安全性。

這種方法的缺點:

由於確切的邏輯是在運行時推斷的,所以這種方法非常耗費CPU資源。 鹽的長度越長,這種方法的CPU密集度越高。

驗證不正確的密碼將涉及最高的CPU成本。 這可能會對合法請求產生反作用,但會增強對攻擊者的安全性。

這種方法可以以各種方式實現,並且可以通過使用可變寬度的鹽和/或醃製密碼哈希來更加安全。

對數據庫存儲進行散列密碼時,我總是使用適當的每個條目salt字符串。 為了我的需要,將鹽存儲在散列密碼旁邊的數據庫中一直運行良好。

但是,有些人建議將salt與數據庫分開存儲。 他們的觀點是,如果數據庫受到攻擊,攻擊者仍然可以建立一個彩虹表並考慮特定的鹽串,以便一次破解一個帳戶。 如果此帳戶具有管理員權限,那麼他甚至可能不需要破解任何其他人。

從安全角度來看,將鹽儲存在不同的地方值得嗎? 考慮在同一台計算機上使用服務器代碼和數據庫的Web應用程序。 如果salt存儲在該機器上的平面文件中,那麼很可能如果數據庫受到損害,salt文件也會出現。

有沒有推薦的解決方案?




彩虹表的重點在於它們是預先創建的,並且可以大規模地分發以節省其他人的計算時間 - 只需在飛行中生成彩虹表就可以直接生成彩虹表,因為它可以直接破解密碼+鹽組合(因為有效的辦法是在生成彩虹表時預先運行用於強制散列的計算),因此通過了解鹽可以“生成彩虹表”這一說法是虛假的。

將salt存儲在單獨的文件中並沒有真正的意義,只要它們是基於每個用戶的就可以了 - 鹽的重點只不過是讓一個彩虹表無法破壞數據庫中的每個密碼。




基於開發由William Penberthy編寫的ASP.NET MVC 4 Web應用程序:

  1. 訪問存儲在單獨數據庫中的鹽需要黑客破解兩個不同的數據庫以獲取鹽和醃製密碼。 將它們存儲在與密碼相同的表中,或者甚至是同一數據庫的另一個表中,意味著當黑客獲得對數據庫的訪問權限時,它們將有權訪問salt和密碼哈希。 由於安全包括將黑客入侵系統的過程太昂貴或耗時,因此黑客必須獲得的訪問量翻倍才能使系統更安全。
  2. 易用性是將鹽保留在與散列密碼相同的數據庫中的主要原因。 您不必確保兩個數據庫始終可用,並始終保持同步。 如果每個用戶都有隨機鹽,那麼使用鹽的好處是最小的,因為儘管它可能更容易發現個人密碼,但破解整個系統的密碼所需的力量將很高。 在這個討論層面,這確實是期望的:保護密碼。 如果黑客已經獲得了數據庫的副本,那麼您的應用程序數據已經被盜用。 此時,問題是由於共享密碼的潛力而降低用戶的風險。
  3. 維護兩個單獨的鏈接數據庫的要求非常廣泛。 當然,它增加了安全感,但它提供的唯一優點是它可以保護密碼,即單一數據元素。 如果數據庫中的每個字段都單獨加密,並且使用了相同的鹽,則將其與數據分開存儲會更有意義,因為系統的基本安全性得到了增強。



通常,它們被前置到散列並存儲在相同的字段中。

不需要單獨存儲它們 - 關鍵是為每個密碼使用一個隨機鹽,以便單個彩虹表不能用於整套密碼哈希值。 使用隨機鹽,攻擊者必須分別強制每個哈希值(或者為所有可能的鹽計算一個彩虹表 - 大大增加工作量)。

如果你有一個更安全的存儲位置,在那裡存儲哈希值是有意義的。




I usually use SHA1 and salt with the user ID (or some other user-specific piece of information), and sometimes I additionally use a constant salt (so I have 2 parts to the salt).

SHA1 is now also considered somewhat compromised, but to a far lesser degree than MD5. By using a salt (any salt), you're preventing the use of a generic rainbow table to attack your hashes (some people have even had success using Google as a sort of rainbow table by searching for the hash). An attacker could conceivably generate a rainbow table using your salt, so that's why you should include a user-specific salt. That way, they will have to generate a rainbow table for each and every record in your system, not just one for your entire system! With that type of salting, even MD5 is decently secure.





security authentication hash cryptography salt