在 PHP 中处理密码加密时,crypt() 和 password_hash() 都可以用来生成密码的哈希值,但这两个函数有明显的区别。在选择加密函数时,理解它们各自的原理和优势,对于确保应用的安全性至关重要。
crypt() 是一个历史悠久的加密函数,可以追溯到 Unix 系统。它支持多种加密算法(如 DES、MD5、SHA-256、SHA-512),具体取决于你提供的盐值(salt)和系统支持的算法。
$password = 'mySecretPassword';
$salt = '$6$rounds=5000$anexamplesaltstring$'; // 使用 SHA-512
$hash = crypt($password, $salt);
生成的 $hash 会根据提供的 salt 格式选择加密算法。在这个例子中使用的是 SHA-512。
password_hash() 是从 PHP 5.5 开始引入的现代化密码哈希函数。它默认使用 bcrypt 算法,并在较新的版本中还支持 argon2i 和 argon2id(PHP 7.2 之后)。它专为密码哈希而设计,自动管理盐值和成本因子,极大地简化了安全编码工作。
$password = 'mySecretPassword';
$hash = password_hash($password, PASSWORD_DEFAULT); // 默认使用 bcrypt
生成的 $hash 是一个包含算法信息、成本和 salt 的字符串,无需开发者手动设置。
特性 | crypt() | password_hash() |
---|---|---|
盐值管理 | 需开发者手动设置 | 自动生成 |
算法 | 多种,需指定 | 默认 bcrypt,支持 argon2 |
安全性 | 取决于实现和配置 | 默认安全,遵循最佳实践 |
易用性 | 复杂,易出错 | 简单,易于使用 |
推荐程度 | 不推荐用于新项目 | 强烈推荐 |
password_hash() 使用的算法专为哈希密码而设计(如 bcrypt 和 argon2),能抵抗现代密码破解技术,如 GPU 加速攻击。
使用 PASSWORD_DEFAULT 常量,PHP 可以自动切换到更安全的算法而无需更改代码。例如:
$hash = password_hash($password, PASSWORD_DEFAULT);
随着 PHP 的更新,PASSWORD_DEFAULT 会自动采用更强的算法,比如从 bcrypt 切换到 argon2id。
由于 password_hash() 自动处理盐值和成本因子,它大幅减少了因为人为设置错误而造成的安全问题。
如果你在构建一个用户认证系统,例如以下形式的注册处理脚本:
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$password = $_POST['password'];
$hash = password_hash($password, PASSWORD_DEFAULT);
// 保存到数据库
$conn = new PDO('mysql:host=localhost;dbname=example', 'user', 'pass');
$stmt = $conn->prepare('INSERT INTO users (username, password) VALUES (?, ?)');
$stmt->execute([$_POST['username'], $hash]);
header('Location: https://m66.net/login-success');
}
在这种情况下,使用 password_hash() 明显更安全、更现代,并能长期维持系统的安全性和可维护性。
虽然 crypt() 仍然可以使用,但从安全性、易用性和未来可维护性角度考虑,password_hash() 是更合适的选择。特别是在处理用户密码的场景中,应优先采用 password_hash() 搭配 password_verify() 来验证用户输入,构建更安全的 PHP 应用。