2012-06-15 16 views
6

在向網站驗證用戶身份時,是否應在數據庫或網站中完成哈希生成和比較?執行密碼比較的最佳做法

我的觀點是網站應該將用戶提供的密碼(可能由網絡服務器加密)傳遞給數據庫。然後數據庫用鹽重新加密並比較哈希值。數據庫響應Web服務器,無論用戶的憑據是否有效。這樣,有史以來最小的數據庫離開了數據庫,基本上是一個是或否,沒有存儲的憑證信息。缺點是,數據庫必須做更多的工作。

另一個說法是工作應該在Web服務器上完成。在這裏,Web服務器將創建散列並從數據庫請求存儲的散列並進行比較。在這種情況下,salt需要從數據庫傳遞迴Web服務器以創建哈希。但是,隨着網絡服務器數量的增加,工作也是共享的。

我個人認爲第二種方法是潛在的安全風險。如果Web服務器受到危害,可以從數據庫請求鹽和散列並輕易破解。

執行上述操作的最佳做​​法是什麼?我忽略/錯過了什麼?

感謝

回答

3

我懷疑你會遇到的第一個問題(它是一個很大的問題)是你的數據庫沒有密碼哈希函數。當然,它可能具有MD5()和SHA1(),但是這些都是加密哈希函數。它有bcrypt()或scrypt()或PBKDF2()嗎?

使用加密哈希函數而不是密碼哈希函數意味着LinkedIn密碼可能被破解得這麼快。如果你沒有使用上述函數之一,那麼如果你的哈希被泄漏了,你將同樣容易受到攻擊。


你打算在回答你的問題假設你的數據庫確實支持密碼散列算法(使用bcrypt,只是因爲我要挑一個)。兩個備選方案:

哈希數據庫:

$db->query("SELECT COUNT(*) FROM users WHERE username = '?' AND password = BCRYPT(?, (SELECT salt FROM user WHERE username = '?'))", $username, $password, $username); 
if($row['count'] != 1) 
{ 
    // Not authenticated. Throw exception. 
} 

在這種情況下,原始密碼發送到數據庫和一個簡單的是或否(0或1)被返回。這個數據庫通信可以被加密。散列和鹽從不保存在應用程序中。

哈希中的應用:

$db->query("SELECT username, salt, password FROM users WHERE username = '?', $username); 
if(bcrypt($password, $row['salt']) != $row['password']) 
{ 
    // Not authenticated. Throw exception. 
} 

在這種情況下,哈希和鹽從數據庫到應用程序和原始密碼的散列拉和比較有完成。與數據庫的通信仍然可以加密。原始密碼永遠不會保存在數據庫內存中。

爲了提高效率,我們可以假設兩種哈希算法都是用C(或某種編譯語言)編寫的,並且可能由OS提供,因此需要花費相同的時間。應用程序散列選項可通過線路接收更多數據,而數據庫散列選項可發送更多數據並具有更復雜的查詢(實質上是兩個查詢,一個用於獲取salt,另一個用於實現比較)。可能無法按照我編寫該查詢的方式使用索引,但查詢可能會被重寫。由於兩種情況下的數據大小仍然可能是一個TCP數據包,因此速度差異可以忽略不計。由於子查詢,我將這稱爲應用程序哈希選項的勝利。

曝光。我會認爲原始密碼比哈希和鹽更敏感。因此,限制原始密碼的暴露似乎更安全,使應用程序散列最佳做法。

+0

我想我簡化了這個例子,但你仍然可以在數據庫中嵌入加密方法,例如在sql server中使用clr對象 – Blootac

+0

@Blootac好點。我已經爲實際的問題添加了一個答案,假設您的數據庫具有適當的哈希算法。 – Ladadadada

+0

謝謝,正反兩方面的說明很好。 – Blootac

3

您可眺望鹽的目的。

鹽被用來防止對散列密碼的字典攻擊。如果您的密碼是「花生」,並且哈希值爲12345,那麼我可以預先爲字典中的每個單詞(包括您的密碼)生成哈希列表,並通過查找我預先生成的一組密碼來快速找到您的密碼哈希值。這是LinkedIn最近發生的事情。如果密碼是鹽漬的,那麼在妥協數據庫之後,我必須預先爲每個鹽值生成一本字典,這將會非常昂貴。此外,適當的隨機生成的鹽可以防止攻擊者知道你和我有相同的密碼(沒有鹽,我們會有相同的哈希)。

我的觀點是鹽不是一個祕密。它們不是公開信息,但攻擊者可以訪問salt值+散列並不一定意味着密碼已被泄露。

0

計算機安全的一個很好的經驗法則是,如果你必須問,你不應該自己動手。但是,如果您的問題是如果Web服務器受到攻擊而暴露了密碼的詳細信息,那麼一種方法是將身份驗證移至其自己的系統,並且根本不會讓Web服務器訪問密碼數據庫。

+2

我明白你的觀點,但如果沒有人提出問題,沒有人會學習,人們會繼續錯誤地做事。那些不問你應該更關心的問題的人。謝謝你的建議。 – Blootac