在Web開發中,用戶密碼的安全存儲至關重要。雖然PHP中有多種加密方法可以用於密碼保護,但crypt()函數依然是一個經典且有效的工具。它允許開發者利用不同的哈希算法(如Blowfish)來生成不可逆的加密字符串。本文將講解如何將crypt()函數與數據庫結合起來,實現安全的用戶密碼存儲。
PHP的crypt()函數用於單向加密,它接受兩個參數:
string crypt ( string $string , string $salt )
$string是要加密的原始字符串(通常是密碼)
$salt是一個影響加密結果的字符串。不同的salt會產生不同的加密結果。
要使用Blowfish算法進行加密,需要格式化salt,例如:
$salt = '$2y$10$' . bin2hex(random_bytes(11));
$hashed_password = crypt('user_password', $salt);
$2y$10$表示使用Blowfish算法和10輪加密。
將加密後的密碼存入數據庫,需要一個用戶表。以下是一個簡單的用戶表結構:
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL
);
然後用PHP連接數據庫,並插入用戶數據:
<?php
$pdo = new PDO("mysql:host=localhost;dbname=testdb;charset=utf8", "dbuser", "dbpass");
$username = 'testuser';
$password = 'mypassword';
// 生成salt並加密密碼
$salt = '$2y$10$' . bin2hex(random_bytes(11));
$hashed_password = crypt($password, $salt);
// 插入到數據庫
$stmt = $pdo->prepare("INSERT INTO users (username, password) VALUES (:username, :password)");
$stmt->execute([
':username' => $username,
':password' => $hashed_password
]);
?>
登錄時,不能簡單比對明文密碼。我們需要用用戶表中已存儲的加密密碼作為salt再次使用crypt()函數。
<?php
$input_password = 'mypassword';
$username = 'testuser';
$stmt = $pdo->prepare("SELECT password FROM users WHERE username = :username");
$stmt->execute([':username' => $username]);
$stored_hash = $stmt->fetchColumn();
if (crypt($input_password, $stored_hash) === $stored_hash) {
echo "密碼驗證成功。";
} else {
echo "密碼錯誤。";
}
?>
雖然crypt()函數是安全的,但它已經逐漸被password_hash()和password_verify()所取代。 crypt()更適合需要向後兼容舊系統的場景。
不過,在使用crypt()時務必要注意:
永遠使用強隨機的salt,避免使用固定值。
控制加密輪數(例如$2y$10$中的10 ),以增加暴力破解成本。
使用HTTPS連接前端和後端,防止傳輸中密碼被截獲。
避免在URL中傳遞敏感數據,例如:
// 錯誤做法(暴露密碼):
$url = "https://m66.net/reset.php?user=test&pass=mypassword";
// 正確做法:僅使用Token或User ID
$url = "https://m66.net/reset.php?token=abcd1234";
通過合理使用crypt()函數結合數據庫操作,開發者可以實現安全、可靠的用戶密碼存儲機制。儘管現代PHP更推薦使用password_hash()和password_verify() ,但crypt()仍然是一個穩定可用的選擇,特別是在維護舊項目或有特殊需求時。安全實踐的關鍵是始終遵循“不可逆加密+ 強salt + 安全驗證”的原則。