PHP 中的密碼雜湊
PHP 用於伺服器端開發,在構建登入和註冊過程時需要密碼。出於安全目的和隱私問題,我們需要對我們的密碼進行雜湊處理,這樣任何人(包括你和你的資料庫管理員)都無法知道使用者的密碼。
但是,當我們對密碼進行雜湊處理時,當我們想登入時,我們需要對其進行重新雜湊處理。本文詳細介紹了密碼雜湊處理以及如何使用 PHP 內建函式 password_hash()
和 password_verify()
.
PHP 中的密碼雜湊
從使用者那裡收集的資料儲存在資料庫中,任何有權訪問資料庫的人都可以看到這些資料。使用者名稱和地址通常保持原樣;它們不如你帳戶的金鑰重要。
作為使用者密碼的文字字串通過雜湊演算法(bcrypt、md5、sha-1、sha-2)傳遞,以防止按原樣儲存密碼並建立文字的加擾表示。密碼的這個加擾表示被儲存,並且在登入過程中,加擾表示被比較。
內建的 password_hash()
函式使用 bcrypt 演算法,這是 Auth0 推薦的 並用於其客戶群。此外,password_verify()
函式將密碼文字與雜湊值進行比較,並在密碼與雜湊值匹配時返回布林值。
在 PHP 中使用 password_hash()
和 password_verify()
進行密碼雜湊
當使用者訪問你的站點並建立一個新帳戶時,作為 PHP 開發人員,你將確保你的應用程式對密碼進行雜湊處理。為此,我們應用 password_hash()
函式。
<?php
$password = "24FE21121@1*?"; // password the user imputs.
echo password_hash($password, PASSWORD_DEFAULT); // outputs the hashed password
?>
程式碼片段的輸出是:
$2y$10$YRmyqWGiHbDSI31XbD2DuOzmTKSjYSSgR.2.3rYCmSSFS/xlAtb3.
程式碼片段使用預設雜湊演算法,根據 PHP 文件,該演算法使用 bcrypt 演算法。如果我們打算改變雜湊演算法,我們可以改變函式的第二個引數。
我們可以使用其他三個可能的引數(雜湊演算法)。PASSWORD_BCRYPT
、PASSWORD_ARGON2I
和 PASSWORD_ARGON2ID
是支援的引數。
PASSWORD_BCRYPT
使用 CRYPT_BLOWFISH
演算法,PASSWORD_ARGON2I
使用 Argon2i
雜湊演算法,而 PASSWORD_ARGON2ID
使用 Argon2id
雜湊演算法。要更好地瞭解每種演算法的工作原理,請檢視 PHP 密碼雜湊文件。
讓我們在我們的程式碼中嘗試 PASSWORD_BCRYPT
引數。
<?php
$password = "24FE21121@1*?"; // password the user imputs.
echo password_hash($password, PASSWORD_DEFAULT); // outputs the hashed password
?>
程式碼片段的輸出是:
$2y$10$vNfovWay8hSq5ixa/lOPK.4YMVX1kgYCBPDEdvz3zM/EBUiBUukpO
PASSWORD_DEFAULT
和 PASSWORD_BCRYPT
都使用 $2y$
識別符號,並將生成 60 個字元的字串。通過上述過程,我們成功地對使用者的密碼進行了雜湊處理。
現在,如果使用者想登入他的帳戶,我們需要將他們輸入的密碼與雜湊密碼進行比較。這就是 password_verify()
發揮作用的地方。
我們可以將密碼和儲存的雜湊密碼與內建函式進行比較。
<?php
$password = "24FE21121@1*?";
$hashed_password ='$2y$10$YRmyqWGiHbDSI31XbD2DuOzmTKSjYSSgR.2.3rYCmSSFS/xlAtb3.';
print_r(password_verify($password, $hashed_password));
?>
程式碼片段的輸出是:
1
在 PHP 中,1 代表真
,0 代表假
。
讓我們對由 PASSWORD_BCRYPT
引數生成的雜湊密碼嘗試 password_verify()
函式。
<?php
$password = "24FE21121@1*?";
$hashed_password = '$2y$10$vNfovWay8hSq5ixa/lOPK.4YMVX1kgYCBPDEdvz3zM/EBUiBUukpO';
print_r(password_verify($password, $hashed_password));
?>
程式碼片段的輸出是:
1
無論我們使用什麼雜湊密碼,password_verify()
函式都可以工作的原因是因為該函式驗證與 crypt()
相容的給定雜湊匹配,兩者兼而有之。此外,這些函式將演算法、成本和鹽作為返回雜湊的一部分返回,並且可以安全地抵禦計時攻擊。
要改善你的雜湊結果,請在 password_hash()
函式中指定成本和鹽選項。但是,如果你不瞭解如何使用它,它會極大地影響你的安全。
要檢查 password_verify()
函式是否會捕獲錯誤密碼,讓我們輸入一個錯誤密碼(從 24FE21121@1*?
更改為 24Fqqw1121@1*?
)。
<?php
$password = "24Fqqw1121@1*?";
$hashed_password = '$2y$10$vNfovWay8hSq5ixa/lOPK.4YMVX1kgYCBPDEdvz3zM/EBUiBUukpO';
if (password_verify($password, $hashed_password)) {
echo "Password Matches!";
} else {
echo "Wrong Password";
}
?>
程式碼片段的輸出是:
Wrong Password
如果我們在實際登入過程的上下文中使用它,程式碼可能如下所示:
<?php
$connect = mysqli_connect($localhost, $username, $password, $database);
if (isset($_POST['submit'])) {
extract($_POST);
// retrive stored hashed password
$sqlQuery = mysqli_query($connect, "SELECT * FROM USERTABLE WHERE USER='$username'");
$fetch = mysqli_fetch_array($sqlQuery);
$currentPassword = $fetch['hashPassword'];
if (password_verify($enteredPassword, $currentPassword)) {
// password matches
$_SESSION['id'] = $fetch['id'];
header("location: home.php");
} else {
// password doesn't match
$output = "Wrong Passworfd";
}
}
Olorunfemi is a lover of technology and computers. In addition, I write technology and coding content for developers and hobbyists. When not working, I learn to design, among other things.
LinkedIn