2011-04-07 80 views
3

閱讀this excellent answer約密碼哈希,不知道如何實現它:如何正確實現hash_hmac?

The Wicked Flea寫道:

生成每個用戶的隨機數;僅這一件就擊敗了彩虹桌。這是一個隨機數,它取決於範圍,擴展了產生的散列數。

那麼除了用戶的密碼在我的數據庫中存儲唯一的令牌嗎?

的示例代碼在原崗位:

function hash_password($password, $nonce) { 
    global $site_key; 
    return hash_hmac('sha512', $password . $nonce, $site_key); 
} 

我如何可以驗證此代碼密碼?讓我來解釋:

當用戶提交自己的密碼,我需要生成它的散列,以檢查其中的電子郵件地址哈希密碼匹配現有的數據庫行。當我對用戶'$nonce一無所知時,我如何選擇這一行?我錯過了什麼嗎?也許我需要通過只有他的電子郵件地址選擇用戶,然後再驗證密碼散列?

順便說一句,你推薦這種哈希方法?

+0

您不需要選擇使用密碼作爲選擇標準的用戶。只需根據電子郵件地址或登錄等獨特特徵選擇用戶,然後再檢查密碼。也見有關哈希想法的一個相關問題(免責聲明:我就此回答):http://stackoverflow.com/questions/3787346/email-address-as-password-salt/3787414#3787414 – Archimedix 2011-04-07 10:27:38

+1

順便說一句,通過用戶名只選擇還有一個好處,你可以顯示「用戶不存在」或「密碼無效」,這取決於錯誤,這極大地增加了你網站的可用性。有時候,無論出於何種原因,你都必須使用不同的用戶名,並且經過很長時間,你可能會嘗試使用舊的密碼和大量的密碼,因爲它只是說「登錄失敗」。有了「用戶不存在」的錯誤,這將不是必需的 – ThiefMaster 2011-04-07 10:33:23

+0

@Archimedix感謝您的回覆。順便說一句,抱歉,但我看不出將系統範圍的鹽添加到明文密碼或密鑰之間的區別。你能說明一下嗎? – fabrik 2011-04-07 10:48:37

回答

3

我想你已經明白了這個想法。在一般的UNIX風格的鹽醃密碼中應用了相同的概念 - 以明文形式存儲salt並使用密碼進行檢索,然後使用salt和提供的密碼生成與存儲值相比較的新散列。

它是由你來考慮無論您信任你的數據庫服務器(以及它的連接)使用由數據庫支持的哈希算法,讓DB做數學題:

SELECT * FROM users WHERE email = 'email' AND password = SHA1(CONCAT('cleartextpass',nonce)); 

或者,您可以在檢索所有匹配的電子郵件後,在代碼中進行數學運算。

編輯:上區分丟失的用戶密碼無效的ThiefMaster評論是經典的安全漏洞,允許攻擊者獲得的有效用戶名列表,並集中在打破自己的密碼,而不是捕魚那黑暗。我強烈建議它。

+0

你能解釋一下你的答案嗎?這並不完全清楚'nonce'來自哪個查詢。基本上你的解決方案對我來說更好,因爲它只能通過數據庫查詢來完成。 – fabrik 2011-04-07 10:52:18

+0

在SQL查詢中,_nonce_是表列的名稱(注意,它未被引用)。 這意味着CONCAT()採用明文密碼並附加在字段_nonce_ – Laas 2011-04-07 11:01:25

+0

中,並且我也可以在SQL和PHP中生成SHA1密鑰,對嗎?我可以將這個* nonce *字段用於其他目的嗎?忘記密碼令牌等?或者這會是一個安全缺陷? – fabrik 2011-04-07 11:07:55