最近,我一直在嘗試在網(wǎng)路上偶然發(fā)現(xiàn)的登入腳本上實(shí)現(xiàn)自己的安全性。在努力學(xué)習(xí)如何製作自己的腳本為每個(gè)用戶生成鹽之後,我偶然發(fā)現(xiàn)了 password_hash
。
據(jù)我了解(基於本頁(yè)的閱讀),當(dāng)您使用 password_hash
時(shí),鹽已經(jīng)在行中生成。這是真的?
我的另一個(gè)問(wèn)題是,有 2 種鹽不是明智的嗎?一種直接在文件中,一種在資料庫(kù)中?這樣,如果有人破壞了資料庫(kù)中的鹽,您仍然可以直接在文件中保存鹽嗎?我在這裡讀到,儲(chǔ)存鹽從來(lái)都不是一個(gè)聰明的主意,但它總是讓我困惑人們的意思。
是的,您理解正確,函數(shù)password_hash()將自行產(chǎn)生鹽,並將其包含在產(chǎn)生的雜湊值中。將鹽儲(chǔ)存在資料庫(kù)中是絕對(duì)正確的,即使已知它也能完成其工作。
// Hash a new password for storing in the database. // The function automatically generates a cryptographically safe salt. $hashToStoreInDb = password_hash($_POST['password'], PASSWORD_DEFAULT); // Check if the hash of the entered login password, matches the stored hash. // The salt and the cost factor will be extracted from $existingHashFromDb. $isPasswordCorrect = password_verify($_POST['password'], $existingHashFromDb);
您提到的第二個(gè)鹽(儲(chǔ)存在檔案中的鹽)實(shí)際上是胡椒或伺服器端密鑰。如果你在散列之前添加它(就像鹽一樣),那麼你就添加了胡椒粉。不過(guò),有一種更好的方法,您可以先計(jì)算雜湊值,然後使用伺服器端金鑰加密(雙向)雜湊值。這使您可以在必要時(shí)更改密鑰。
與鹽相反,這個(gè)密鑰應(yīng)該保密。人們經(jīng)常混淆它並試圖隱藏鹽,但最好讓鹽發(fā)揮作用並用密鑰添加秘密。
建議使用password_hash
來(lái)儲(chǔ)存密碼。不要將它們分成資料庫(kù)和檔案。
假設(shè)我們有以下輸入:
$password = $_POST['password'];
您首先執(zhí)行以下操作對(duì)密碼進(jìn)行雜湊處理:
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
然後查看輸出:
var_dump($hashed_password);
正如你所看到的,它是經(jīng)過(guò)哈希處理的。 (我假設(shè)您執(zhí)行了這些步驟)。
現(xiàn)在,您將此雜湊密碼儲(chǔ)存在資料庫(kù)中,確保您的密碼列足夠大以容納雜湊值(至少 60 個(gè)字元或更長(zhǎng))。當(dāng)使用者要求登入時(shí),您可以使用資料庫(kù)中的雜湊值檢查輸入的密碼,方法如下:
// Query the database for username and password // ... if(password_verify($password, $hashed_password)) { // If the password inputs matched the hashed password in the database // Do something, you know... log them in. } // Else, Redirect them back to the login page.