在構建網站或應用程序時,用戶認證系統的安全性是一個重要的考量因素。 PHP 提供了多種方式來實現密碼的加密與驗證,其中crypt()函數是一種經典且功能強大的加密工具。本文將講解如何使用crypt()函數構建一個安全的用戶註冊與登錄系統,包括密碼的加密、驗證和用戶數據的處理。
crypt()是PHP 提供的一個加密函數,使用單向散列算法對字符串進行加密。它支持多種加密算法(如MD5、SHA-256、SHA-512 和Blowfish),具體取決於提供的salt(鹽)格式。
string crypt ( string $str , string $salt )
salt的值決定了加密算法的類型和行為。為了安全,建議使用支持SHA-512 或Blowfish 的salt。
用戶註冊時,我們需要對密碼進行加密後再存入數據庫,確保即使數據庫洩露,攻擊者也無法輕易還原密碼。
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$username = $_POST['username'];
$password = $_POST['password'];
// 創建一個強鹽並加密密碼(使用SHA-512)
$salt = '$6$' . bin2hex(random_bytes(16)) . '$'; // SHA-512
$hashed_password = crypt($password, $salt);
// 保存用戶名和加密後的密碼到數據庫(以SQLite為例)
$db = new PDO('sqlite:users.db');
$stmt = $db->prepare("INSERT INTO users (username, password) VALUES (?, ?)");
$stmt->execute([$username, $hashed_password]);
echo "註冊成功,請 <a href='https://m66.net/login.php'>登入</a>。";
}
?>
HTML 註冊表單:
<form method="POST" action="">
使用者名稱:<input type="text" name="username" required><br>
密碼:<input type="password" name="password" required><br>
<input type="submit" value="註冊">
</form>
登錄時,我們不需要知道原始密碼。只需將用戶輸入的密碼使用數據庫中相同的salt 進行crypt()加密,然後與存儲的hash 比較即可。
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$username = $_POST['username'];
$password_input = $_POST['password'];
$db = new PDO('sqlite:users.db');
$stmt = $db->prepare("SELECT password FROM users WHERE username = ?");
$stmt->execute([$username]);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if ($row) {
$hashed_password = $row['password'];
if (crypt($password_input, $hashed_password) === $hashed_password) {
echo "登入成功!歡迎回來,{$username}。";
} else {
echo "密碼错误。";
}
} else {
echo "用戶不存在。";
}
}
?>
HTML 登錄表單:
<form method="POST" action="">
使用者名稱:<input type="text" name="username" required><br>
密碼:<input type="password" name="password" required><br>
<input type="submit" value="登入">
</form>
CREATE TABLE users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT UNIQUE NOT NULL,
password TEXT NOT NULL
);
使用HTTPS :確保所有表單傳輸都通過加密連接進行。
添加CSRF 保護:防止跨站請求偽造攻擊。
限制登錄嘗試次數:防止暴力破解。
及時更新PHP 版本:保持加密算法和函數的安全性。
使用更現代的函數(如password_hash)時可參考本文邏輯:雖然crypt()是有效的,但現代PHP 推薦使用password_hash()和password_verify() 。
通過合理使用crypt()函數以及配套的密碼驗證邏輯,我們可以構建一個相對安全的用戶認證系統。雖然現代PHP 提供了更高級的接口,如password_hash() ,但了解crypt()的工作原理仍有助於深入理解密碼加密的本質。在某些低版本PHP 環境或特殊兼容需求下, crypt()依然是一個實用的選擇。