php 8.1 中应首选 password_argon2id 或 password_argon2i 算法,显式配置 memory_cost(如65536)、time_cost(如4)、threads(如2),哈希结果直接存 varchar(255),验证仅用 password_verify()。

PHP 8.1 中使用 password_hash() 处理密码,核心原则是:**不自己造轮子、不控制盐值、不降级算法、不跳过验证逻辑**。它已内置安全设计,关键在于用对参数、配对验证、规避常见误操作。
选对算法:优先用 PASSWORD_ARGON2I 或 PASSWORD_ARGON2ID
PHP 7.2+ 支持 Argon2(2015 年密码哈希竞赛冠军),比 bcrypt 更抗 GPU/ASIC 暴力破解。在 PHP 8.1 环境下,只要系统支持 libsodium(默认启用),应首选:
-
PASSWORD_ARGON2ID:兼顾抵抗侧信道攻击(如时序分析)和抵御 GPU 加速破解,适合大多数 Web 应用 -
PASSWORD_ARGON2I:纯内存硬性,更侧重防 GPU 破解,适合高敏感场景 - 避免仅用
PASSWORD_BCRYPT(虽仍安全),因其固定 64 字节输入、不抗定制硬件,且无法调整内存成本
合理配置选项:内存、时间、线程不可设为“默认”
Argon2 的安全性高度依赖运行参数。PHP 不提供全局默认值,必须显式传入 $options 数组:
-
'memory_cost' => 65536(即 64MB):最低推荐值,太低易被暴力;太高可能触发服务器内存限制 -
'time_cost' => 4:迭代轮数,建议 3–6;值越大越慢但越安全,需在响应延迟(通常 ≤ 100ms)和强度间平衡 -
'threads' => 2:并行线程数,设为 CPU 核心数的一半较稳妥;设 1 可规避某些共享主机的并发限制
示例:
password_hash($password, PASSWORD_ARGON2ID, ['memory_cost' => 65536,
'time_cost' => 4,
'threads' => 2
]);
存储与验证:哈希字符串直接入库,验证只用 password_verify()
password_hash() 返回完整字符串(含算法标识、参数、盐、哈希值),长度约 90–120 字符,应存为 VARCHAR(255) 字段,不可截断或二次编码。
- 验证时只调用
password_verify($input, $hash_from_db),由 PHP 内部自动解析参数并重算——不要自己拆解哈希、不要手动比对 - 若未来升级算法(如迁移到新 Argon2 参数或更新标准),旧哈希仍可被
password_verify()正确识别并兼容处理 - 数据库字段无需额外存盐或算法名,一切已内嵌
避开典型陷阱:类型、上下文、错误处理
- 确保密码字段接收的是字符串:若用户提交空值、
null或数组,password_hash()可能静默失败或产生弱哈希。建议前置检查:is_string($password) && strlen($password) >= 8 - 不要在 SQL 查询中拼接哈希结果,即使它“看起来安全”。始终用预处理语句插入/查询
- 不记录原始密码、不日志打印哈希值(哪怕只是调试)、不在错误信息中暴露哈希结构
- 生产环境关闭
display_errors,防止因参数错误导致警告泄露哈希片段
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











