2010-11-09 95 views
1

我使用salt加密我的用戶密碼。 我正在使用PHP,下面是用戶註冊期間發生的事情的快速示例。用鹽認證用戶登錄

這就是:

PHP代碼:

// Gives me my random key. My salt generator. 
    $salt = uniqid(mt_rand()); 

    // My password via what users inputs. 
    $userpwd; 

    // Then the encryption. I use a HMAC hash. 
    $encrypted = hmac_hash("sha256", $userpwd, $salt); 
?> 

現在,在我的劇本都爲我工作。但我的問題是,我如何認證用戶登錄?新的加密密碼是隨機的,所以我無法將登錄表單中的密碼與數據庫中保存的加密密碼進行比較。

我搜索了並找不到解決方案。也許我沒有足夠努力搜索,但有沒有解密密碼的方法?我可以通過腳本來驗證用戶身份?

回答

3

您以同樣的方式散列用戶輸入的密碼,然後比較散列是否與您存儲的密碼相同。

if (hmac_hash("sha256", $_POST['password'], $saltFromDatabase) === $hashFromDatabase) 
    $login = true; 

您還必須存儲鹽,因爲它對每個用戶都不同。我還建議使用在應用程序中保持不變的第二個salt(存儲在硬配置文件中,這樣即使數據庫受到攻擊,密碼仍然安全)。

注意:散列是不是與加密相同;這是一個不可逆轉的過程。

+0

謝謝,那就是我會做的。我把我的鹽儲存在配置文件中。我讀過很多人說將鹽儲存在分貝中,但是我對它感到不舒服。只是將數據庫妥協了。 – Mario 2010-11-09 14:31:10

+1

但請記住,爲每個人使用相同的鹽會減少強力攻擊者所需的計算時間。 – 2010-11-09 15:05:19

+0

如果不止一個人擁有相同的密碼,它也會導致相同的散列。每個用戶有一個鹽(每個密碼)要好得多。 – Aether 2010-11-09 16:09:25

0

你不解密你存儲的內容。您對輸入的密碼進行散列並將其與註冊時存儲的密碼進行比較。這是因爲如果兩個哈希匹配(所有意圖和目的),您可以確信源數據匹配。

-2

你的鹽需要是恆定的,而不是隨機的。通過這種方式,當你對密碼進行密碼檢查時,你所要做的就是再次用鹽對輸入進行哈希處理,結果的哈希應該與之前出現的相同。

+0

好的。所以不要隨機產生鹽?使用恆定的鹽?我讀過很多人在db中保存鹽串。這是一個很好的做法嗎? – Mario 2010-11-09 14:27:59

+1

根據定義,鹽不*常數,而是隨機值。 http://stackoverflow.com/questions/1645161/salt-generation-and-open-source-software/1645190#1645190 – Jacco 2010-11-09 14:59:12

+0

@Jacco常數到密碼標識的那條信息。所以在這種情況下,可能是一些用戶特定的數據。獨特,而不是隨機的。 – 2010-11-09 19:14:44

8

您需要爲每個用戶的密碼生成一個唯一的salt,然後將salt的值存儲在某個可以檢索它的地方。例如,通過將鹽保存到user表以及用戶名和散列密碼。這樣,當你去認證一個用戶時,你可以提取已知的salt並通過你的函數運行它。

這裏是一個包含更多信息的文章:Storing Passwords - done right!

以及有關鹽的更多信息:salt-generation-and-open-source-software

+0

不知道爲什麼這會被低估... – 2010-11-09 14:51:19

+0

鹽必須是隨機的。 (如果它不是隨機的,我們稱之爲關鍵)http://stackoverflow.com/questions/1645161/salt-generation-and-open-source-software/1645190#1645190 – Jacco 2010-11-09 14:58:02

+3

當然。在那篇文章中:「每當你創建一個新密碼或更改密碼時都要使用新鹽」。我同意每次生成密碼時都需要計算新的獨特的鹽。然後,您可以按照我的建議將該鹽存儲在數據庫中。我看到我的答案真的沒有解釋清楚,所以我修改了它... – 2010-11-09 15:50:08

0

你加密用於登錄,並與數據庫中的加密的密碼進行比較的密碼。 :)

0

您計算用戶輸入的密碼的哈希,就像您在註冊時一樣。請注意,代碼是半僞代碼,您需要將其調整爲您的庫或函數。

$res = db('SELECT etc FROM users WHERE user=? AND pass=?', 
    $_POST['user'], hmac_hash("sha256", $_POST['pass'], $salt)); 
if(numRows($res) > 0) { 
    // continue with authentication 
} 

如果鹽存儲在數據庫,那麼你就必須要麼第一取水的時候,還是在數據庫進行比較。

+1

你應該首先從數據庫中獲取salt,而不是將非哈希密碼發送到數據庫。 – Jacco 2010-11-09 15:05:11