PHP密码哈希与安全存储
PHP密码哈希与安全存储
密码存储是Web安全中最重要的一环。PHP提供了password_hash和password_verify。今天说说密码安全的完整方案。
密码不要用md5或sha1存储。这些算法太快了,暴力破解很容易。
```php
$password = 'UserPassword123!';
$hash = password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]);
echo "Bcrypt: $hash\n";
if (password_verify($password, $hash)) {
echo "验证成功\n";
}
// PHP8.0+ 推荐用Argon2id
$hash2 = password_hash($password, PASSWORD_ARGON2ID);
echo "Argon2id: $hash2\n";
// 检查是否需要升级哈希算法
if (password_needs_rehash($hash, PASSWORD_ARGON2ID)) {
$newHash = password_hash($password, PASSWORD_ARGON2ID);
echo "哈希已升级\n";
}
?>
>
用户注册和登录的密码处理。
```php
class AuthService
{
private PDO $pdo;
public function __construct(PDO $pdo)
{
$this->pdo = $pdo;
}
public function register(string $email, string $password): int
{
$hash = password_hash($password, PASSWORD_ARGON2ID);
$stmt = $this->pdo->prepare("INSERT INTO users (email, password) VALUES (?, ?)");
$stmt->execute([$email, $hash]);
return (int)$this->pdo->lastInsertId();
}
public function login(string $email, string $password): bool
{
$stmt = $this->pdo->prepare("SELECT * FROM users WHERE email = ?");
$stmt->execute([$email]);
$user = $stmt->fetch();
if (!$user) return false;
if (password_verify($password, $user['password'])) {
// 检查是否需要重新哈希
if (password_needs_rehash($user['password'], PASSWORD_ARGON2ID)) {
$newHash = password_hash($password, PASSWORD_ARGON2ID);
$stmt = $this->pdo->prepare("UPDATE users SET password = ? WHERE id = ?");
$stmt->execute([$newHash, $user['id']]);
}
return true;
}
return false;
}
}
?>
密码强度验证。
```php
function validatePassword(string $password): array
{
$errors = [];
if (strlen($password) < 8) $errors[] = '至少8个字符';
if (!preg_match('/[a-z]/', $password)) $errors[] = '需要小写字母';
if (!preg_match('/[A-Z]/', $password)) $errors[] = '需要大写字母';
if (!preg_match('/\d/', $password)) $errors[] = '需要数字';
if (!preg_match('/[@$!%*?&]/', $password)) $errors[] = '需要特殊字符';
return $errors;
}
function passwordStrength(string $password): string
{
$score = 0;
if (strlen($password) >= 8) $score++;
if (strlen($password) >= 12) $score++;
if (preg_match('/[a-z]/', $password)) $score++;
if (preg_match('/[A-Z]/', $password)) $score++;
if (preg_match('/\d/', $password)) $score++;
if (preg_match('/[^a-zA-Z0-9]/', $password)) $score++;
return match (true) {
$score >= 6 => '很强',
$score >= 4 => '强',
$score >= 2 => '中',
default => '弱',
};
}
echo passwordStrength('abc123') . "\n";
echo passwordStrength('Abc12345!') . "\n";
print_r(validatePassword('weak'));
?>
密码安全的最佳实践。password_hash用Bcrypt或Argon2id,cost参数设到12左右。密码长度至少8位,包含大小写字母、数字和特殊字符。存储前做哈希处理,绝不存明文密码。
更多推荐
所有评论(0)