本文目录导读:

- 推荐方法:使用
password_hash()和password_verify() - 更安全的选择:Argon2i / Argon2id
- 需要重新计算哈希吗?(密码时效检查)
- ⚠️ 常见错误(不要这样做)
- 数据库字段设计
- 扩展:盐值(Salt)
在PHP项目中,密码加密存储的最佳实践是使用密码哈希函数,而不是简单的加密或摘要算法。
核心原则:永远不要明文存储密码,也不要使用MD5、SHA1等简单哈希。
下面是推荐的几种安全且标准的密码加密存储方法:
推荐方法:使用 password_hash() 和 password_verify()
这是PHP官方推荐的最安全、最简便的方法,从PHP 5.5.0版本开始内置支持。
注册/修改密码时:
<?php // 用户提交的明文密码 $plainPassword = $_POST['password']; // 使用 password_hash() 进行哈希 // 参数1:明文密码 // 参数2:加密算法(推荐 PASSWORD_BCRYPT 或 PASSWORD_ARGON2I/ID) // 参数3(可选):选项数组 $hashedPassword = password_hash($plainPassword, PASSWORD_BCRYPT); // 或者使用更安全的 Argon2i (PHP >= 7.2) // $hashedPassword = password_hash($plainPassword, PASSWORD_ARGON2I); // 将 $hashedPassword 存入数据库(字段建议 varchar(255)) echo $hashedPassword; // 类似于: $2y$10$..... ?>
登录验证时:
<?php
// 用户输入的密码
$inputPassword = $_POST['password'];
// 从数据库读取的密码哈希值
$storedHash = '从数据库获取的哈希值字符串';
// 使用 password_verify() 验证
if (password_verify($inputPassword, $storedHash)) {
echo "密码正确,登录成功!";
// 开始用户会话
} else {
echo "密码错误!";
}
?>
优点:
- 自动生成强随机盐值(Salt)。
- 可以根据硬件性能调整算法成本(Cost Factor),这是通过
cost参数(对Bcrypt)或memory_cost、time_cost等(对Argon2)实现的。 - 算法可以升级,无需修改现有密码。
更安全的选择:Argon2i / Argon2id
如果你的PHP版本 >= 7.2,可以使用Argon2i或Argon2id算法,它比Bcrypt更抗GPU和ASIC攻击。
<?php
// 使用 Argon2id(推荐,抵抗侧信道和GPU攻击)
$options = [
'memory_cost' => 1 << 17, // 128MB内存(可根据服务器调整)
'time_cost' => 4, // 4次迭代
'threads' => 2 // 并线程数
];
$hashedPassword = password_hash($plainPassword, PASSWORD_ARGON2ID, $options);
?>
需要重新计算哈希吗?(密码时效检查)
当服务器升级或调整了算法成本(如cost从10提高到12),可以用以下方法安全地更新哈希:
<?php
// 登录成功后
if (password_verify($inputPassword, $storedHash)) {
// 检查是否需要重新哈希(算法或成本变化)
if (password_needs_rehash($storedHash, PASSWORD_BCRYPT, ['cost' => 12])) {
// 重新计算哈希并更新数据库
$newHash = password_hash($inputPassword, PASSWORD_BCRYPT, ['cost' => 12]);
// UPDATE users SET password = '$newHash' WHERE id = ...
}
// 登录成功...
}
?>
⚠️ 常见错误(不要这样做)
| 错误做法 | 原因 |
|---|---|
md5($password) |
极不安全,1秒可计算数十亿次,且无盐值 |
sha1($password) |
同样不安全 |
| 自行拼接盐值 | 容易设计出错,且无法自动升级算法 |
双向加密(AES、base64) |
密码不需要解密,只需要验证 |
| 把密码存在Cookie/URL中 | 明文暴露风险 |
数据库字段设计
存储哈希值的字段建议:
ALTER TABLE users MODIFY COLUMN password VARCHAR(255) NOT NULL; -- 或使用 TEXT 类型
- Bcrypt哈希一般60字符长。
- Argon2哈希可能更长(90-128字符),所以用255安全。
扩展:盐值(Salt)
使用password_hash()时,盐值是自动生成的,并包含在哈希结果中,你不需要自行存储盐值——它已经是哈希字符串的一部分。
例如哈希值:
$2y$10$abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ
$2y$= 算法标识10= 成本因子 (2^10次迭代)- 后面22字符 = 盐值
- 剩余部分 = 真正的哈希
最佳实践代码(完整示例):
<?php
// 注册
$hash = password_hash($password, PASSWORD_ARGON2ID, [
'memory_cost' => 65536,
'time_cost' => 4,
'threads' => 3
]);
// 登录验证
if (password_verify($inputPassword, $hashFromDb)) {
// 成功
}
?>
无特殊需求的话,直接用password_hash($password, PASSWORD_DEFAULT)即可(PHP会自动选择当时最安全的默认算法,目前是Bcrypt)。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播