You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP的PASSWORD_DEFAULT哈希算法为何仅验证前8位字符?

问题解答

1. 如何实现完整密码的哈希?

绝对不要手动拼接盐值和密码,password_hash()会自动生成安全的盐值并嵌入最终的哈希字符串中,正确用法是直接传入明文密码:

<?php
$test_pw = "%ImAVery1234Secure!Password$";
$password_hashed = password_hash($test_pw, PASSWORD_DEFAULT);
echo password_verify($test_pw, $password_hashed); // 返回1
?>

你遇到的前8位验证通过的问题,是因为PASSWORD_DEFAULT默认采用的bcrypt算法,最多只处理输入字符串的前72字节——你手动拼接盐值后,前72字节刚好包含盐+前8位密码,导致验证通过。如果使用PHP 7.4及以上版本,PASSWORD_DEFAULT会自动切换为Argon2id算法,该算法没有72字节的输入限制,能完整处理任意长度的密码。

2. 是否必须更换哈希算法?

不需要强制更换,但推荐在PHP版本支持(PHP 7.2+)的情况下,使用PASSWORD_ARGON2ID作为哈希算法,它的安全性比bcrypt更高,且无输入长度限制。

3. 更换算法后,能否使用password_verify验证?

完全可以!password_verify()会自动识别哈希字符串对应的算法,不管是bcrypt、Argon2i还是Argon2id,只要是password_hash()生成的哈希,都能直接用它验证。

绝对不要用password_hash(...) == $db_password这种写法,这种方式会失去哈希算法的自适应特性,还存在时序攻击的风险,password_verify()已经帮你规避了这些安全问题。

4. 现有已哈希的密码能否重新哈希?

不能直接对已哈希的密码重新哈希(哈希是单向不可逆的,无法还原明文),只能在用户下次登录时,获取到用户输入的明文密码,验证旧哈希通过后,再用新算法重新哈希并更新数据库中的记录。示例代码如下:

<?php
// 用户输入的明文密码
$user_input_pw = $_POST['password'];
// 从数据库取出旧哈希
$old_hash = $db->query("SELECT password FROM users WHERE id = ?", [$user_id])->fetchColumn();

if (password_verify($user_input_pw, $old_hash)) {
    // 验证通过,检查当前哈希是否为推荐算法
    $hash_info = password_get_info($old_hash);
    if ($hash_info['algoName'] !== 'argon2id') {
        // 用新算法重新哈希并更新数据库
        $new_hash = password_hash($user_input_pw, PASSWORD_ARGON2ID);
        $db->query("UPDATE users SET password = ? WHERE id = ?", [$new_hash, $user_id]);
    }
    // 登录成功逻辑
} else {
    // 密码错误逻辑
}
?>

内容的提问来源于stack exchange,提问作者CuzImBisonratte

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 23:45:31