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位,包含大小写字母、数字和特殊字符。存储前做哈希处理,绝不存明文密码。
PHP密码哈希与安全存储
张小明
前端开发工程师
SDR实战:用MATLAB搞定无线通信中的频率偏移(附代码避坑指南)
SDR实战:用MATLAB搞定无线通信中的频率偏移(附代码避坑指南)刚接触SDR的朋友们,是否曾被"频偏"这个概念折磨得焦头烂额?那些论文里复杂的公式推导和算法实现,是否让你望而却步?别担心…
Python List底层原理与高性能使用指南
1. 为什么说 List 是 Python 里最值得花时间吃透的数据结构? 在 Python 的所有内置类型中, List 绝对是新手最先接触、老手最常依赖、面试官最爱深挖的那个。它不像 str 那样只管文本,也不像 dict 那样专注键值映射,更不像 tupl…
LangGraph重构RAG:从链式流水线到可编程状态图
1. 项目概述:这不是一个简单的RAG升级,而是一次工作流范式的迁移“Build Advanced RAG with LangGraph”——这个标题里藏着三个关键信号:Advanced(进阶)、RAG(检索增强生成)、LangGraph&#x…
Multisim仿真差动放大电路:从单端/双端输入到共模抑制比,一个实验讲透
Multisim仿真差动放大电路:从单端/双端输入到共模抑制比,一个实验讲透差动放大电路作为模拟电子技术中的核心模块,其对称结构带来的共模抑制能力在传感器信号调理、医疗仪器和通信系统中具有不可替代的作用。但传统教材中抽象的公式推导往往让…
用ESP32的板载LED玩点花样:除了Blink,还能模拟呼吸灯和SOS信号
用ESP32玩转板载LED:从呼吸灯到摩尔斯电码的创意实践当ESP32开发板上的那颗蓝色LED第一次按照你的代码规律闪烁时,那种成就感是每个创客都熟悉的入门仪式。但你是否想过,这颗看似简单的板载LED(通常连接在GPIO2引脚)能…
Word和WPS里‘文本转表格’用对了么?避开这3个坑,效率翻倍!
Word和WPS文本转表格高阶指南:从纠错到效率革命办公软件中的文本转表格功能就像一把瑞士军刀——看似简单却暗藏玄机。许多用户在使用Word或WPS时,虽然知道这个功能的存在,却常常陷入"能用但不好用"的困境。本文将带你跳出基础操作…