2012-04-27 57 views
0

因此,我正在學習PHP並正在登錄頁面上工作。我已經想出瞭如何使用SHA256註冊新用戶來散列$ salt + $密碼。我知道像bcrypt這樣的加密方法較慢,但爲了學習目的,我只使用SHA256。我的問題是,使用這種加密後:從數據庫檢索salt + hash進行驗證

function HashPassword($password) { 
    $salt = bin2hex(mcrypt_create_iv(32, MCRYPT_DEV_URANDOM)); 
    $hash = hash("sha256", $salt . $password); column 
    $final = $salt . $hash; 
    return $final; 
} 

使用準備好的語句,什麼是從數據庫中檢索哈希密碼的最好辦法,所以我可以使用這樣的功能驗證呢?

function ValidatePassword($password, $hash_pass) { 

    $salt = substr($hash_pass, 0, 64); 
    $trueHash = substr($hash_pass, 64, 64); 
    $reHash = hash("sha256" , $salt . $password); 

    return $reHash == $trueHash; 
} 

回答

1

你基本上保存密碼哈希與鹽,使其不能識別。

如果您的數據庫在某些時候被黑客攻擊,黑客無法直接讀取密碼。相反,他將不得不重新創建哈希值。

如果你不爲每個用戶使用不同的(隨機)salt,黑客只需要創建一個包含所有可能的散列值的表並將其與你保存的散列密碼進行比較。

但是,如果每個密碼在密碼之前添加了一個不同的salt,那麼在哈希之前,黑客必須爲每個密碼創建一個新表,從而增加獲取真實密碼所需的工作量。人們希望這會導致黑客效率低下或代價過高。

對於您爲要驗證你必須遵循下面的模式登錄憑證編碼器:

  1. 獲取保存在數據庫中的鹽。
  2. 計算具有的級聯hash = salt + password
  3. 值進行比較計算與保存的一個hash === savedHash
  4. 如果它們是相同的,這是有效的密碼。如果不是,那是一個錯誤的密碼。
+0

是的,我理解這個概念,並感謝你的額外澄清。絆倒我的是我如何訪問我的數據庫中的串聯散列。從用戶密碼中選擇username ='$ username'? – Jukodan 2012-04-27 07:38:59

+0

@Jukodan你可以做一個單一的查詢來檢索salt和散列密碼:'SELECT hashedPW,salt FROM users WHERE username ='$ username''。然後用PHP完成比較。重要的一點是爲每個用戶使用不同的鹽,而不是全球用戶(對另一個答案的評論聽起來像對所有用戶只有一個「鹽」)。 – Sirko 2012-04-27 07:41:40

+0

啊!我一直在想它,主要是因爲當我查詢數據庫並回應我收到「資源ID#2」的結果而不是預期的散列密碼時。目前我正在使用: $ salt = bin2hex(mcrypt_create_iv(32,MCRYPT_DEV_URANDOM)); 爲每個用戶生成一個隨機salt,然後將hash = salt + password存儲在一列中。 – Jukodan 2012-04-27 07:46:18

5

的原則是,你找回密碼;而是使用相同的HashPassword函數計算密碼嘗試的散列值,然後查詢數據庫以查找匹配的記錄。


編輯

HashPassword功能再來看,我知道你不希望在其中生成隨機鹽,而是採取$salt作爲參數;您將傳入現有數據庫記錄的值,或者根據需要傳入隨機生成的值。

+0

雖然鹽呢?我知道人們能夠驗證使用鹽進行散列的登錄。在這種情況下,由於它是隨機生成的,我可以如何驗證...我有點迷路。 – Jukodan 2012-04-27 07:27:54

+3

@Jukodan:你的鹽應該和你的記錄一起存放。 – eggyal 2012-04-27 07:28:15

+0

我把我的salt作爲一個全局類變量(私有)放在包含我需要hash + salt的腳本中。只需輸入他們輸入的密碼,添加鹽,將其存儲在變量中,從數據庫中檢索已經哈希的密碼並比較兩者。如果他們匹配,那麼你是金,如果沒有,那麼他們輸入了錯誤的密碼 – 2012-04-27 07:31:51