2011-06-24 110 views
8

我錯過了什麼嗎?是否有任何額外的步驟將密碼存儲到數據庫?Web應用程序 - 存儲密碼

存放密碼:
       關於這個問題儘可能我來,最好的方式來存儲用戶密碼,在Web應用程序DB這個結論是經過大量的研究(在我的情況的MySQL + PHP)如下:

  • 指定一個站點範圍的靜態鹽。 (16個字符,包括0-9,a-z,A-Z,[]/* - ')
  • 指定每個用戶隨機鹽(存儲在數據庫中)。
  • 存儲結果hash_function($ userPassword + $ sitewideSalt + $ randomSalt)
  • 將$ randomSalt與生成的散列一起存儲。
  • 使用bcrypt調整工作量 散列

  • 攻擊#1:攻擊者通過SQL注入轉儲數據庫。 我們hash_function的
            DB結果和每 用戶鹽隨機。

    轉儲通過查詢自己的帳戶,攻擊者可以 獲得$ userPassword的$ randomSalt後。然後通過猜測散列 函數(如md5),他可以對 $ sitewideSalt開始彩虹攻擊。但這可能需要長達1.41億個 個世紀[1]。

    通過使用這種類型的安全不允許轉儲的數據庫妥協存儲的密碼。用戶仍然需要通過另一種方法找到$ sitewideSalt

  • 攻擊#2:攻擊者找到一個本地文件包含(LFI)載體。
             攻擊者可以獲取我們web應用程序的原始代碼。

    通過可能LFI利用Web應用程序後 或RFI [2]的攻擊者讀取 源代碼我們的web應用 並且獲得我們簡單 算法和存儲
    $ sitewideSalt


在哪裏下?
         現在攻擊者有兩種鹽,他可以開始彩虹獲得實際的密碼。除了他必須爲每個用戶製作1個彩虹表,因爲每個用戶具有不同的隨機用戶特定鹽($ randomSalt)。

「一個現代化的服務器可以計算出約330MB每秒的MD5 哈希值。如果 你的用戶有密碼這是 小寫字母和6個 字符,你可以嘗試每 一個可能的密碼大小約爲40秒的 。「
「...... CUDA,你可以放在一起你自己的小超級計算機集羣,這將讓你嘗試周圍7億口令第二......」 [3]

       ,我們現在需要做的是什麼通過使用諸如bcrypt的耗時算法來擴展哈希函數。 bcrypt的工作負載因子可以是簡單哈希函數的5-6個數量級。破解一個密碼可能需要幾年而不是幾分鐘。作爲獎勵,bcrypt已經爲每個散列生成一個隨機salt並將其存儲在結果散列中。

  1. http://www.grc.com/haystack.htm
  2. http://www.wildcardsecurity.com/security101/index.php?title=Local_File_Inclusion

回答

3

不錯的工作!對我來說看起來非常完整。

只有我會建議是:

旋轉服務鹽。

設計一種方法來週期性地輪換服務範圍的鹽,並定期運用它。

例如,在生成新服務鹽後,將其用於所有新帳戶&任何密碼更改。當現有用戶嘗試登錄時,使用舊的服務鹽進行身份驗證。如果成功,則使用新服務salt(以及可選的新用戶特定鹽)更新其哈希值。對於沒有「登錄一段時間」的用戶,代表他們隨機生成一個新密碼。這將爲已放棄網站的用戶「保持」安全,迫使那些返回的用戶使用密碼重置功能。 ('有些時間'=你適應的任何時期)。

請勿硬編碼您的服務鹽。

不要讓LFI攻擊危害您的服務鹽。在啓動時向服務提供服務鹽,並將其保存在內存中。爲了危害服務salt,攻擊者需要能夠執行代碼從內存中讀取salt。如果攻擊者可以做到這一點,那麼無論如何你都能很好地處理。 =)

不要重複使用用戶鹽。

尋找機會爲用戶提供新的鹽類。用戶更改他的密碼?生成一個新的隨機鹽。這進一步阻礙了暴力破解,迫使你的服務器範圍內的鹽應該是一個攻擊者能夠獲得他的散列,只要他覺得喜歡它。加上這一點,請定期輪換你的服務 - 鹽,我敢打賭,你對強制蠻力有很強的威懾力。

(將其標記爲社區維基,如果其他人有其他想法)。

+0

我有點困惑。服務鹽的邏輯如何用於認證?我猜我在mysql中存儲服務鹽,然後登錄時,我將它附加到用戶散列並存儲散列,並檢查它們是否相等。但是,是不是沒有服務鹽一樣?因爲如果用戶散列和存儲散列匹配,則附加服務鹽也將匹配。 – 2012-07-25 05:11:45

+0

爲什麼你需要定期旋轉鹽? – sam

相關問題