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

使用PHP生成Django可接受的密码哈希不生效如何解决

错误原因

你的代码存在3个核心问题,导致生成的哈希无法被Django正常识别校验:

  • 最核心的问题是hash_pbkdf2返回值格式错误。PHP的该函数默认返回十六进制小写字符串,而Django要求哈希段是原始二进制PBKDF2计算结果的base64编码值。你直接对十六进制字符串做base64编码,得到的结果和Django计算的完全不匹配。调用函数时需要传入第6个参数true,让函数返回原始二进制结果。
  • 盐值生成使用了不安全的随机源。rand()不是密码学安全的随机数生成器,生成的盐值熵不足、可预测,既不符合密码哈希的安全要求,也和Django使用安全随机源生成盐的逻辑不符,应该替换为random_int()。
  • base64编码结果保留了填充符。Django存储哈希时会去掉base64结果末尾的=填充符,你直接使用base64_encode的带填充结果,会导致Django解析校验失败,需要手动去除末尾的填充字符。
修正后可直接使用的代码
$saltLen = 22;
function generateSecureSalt($length) {
    $charSet = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $salt = '';
    $maxIdx = strlen($charSet) - 1;
    for ($i = 0; $i < $length; $i++) {
        $salt .= $charSet[random_int(0, $maxIdx)];
    }
    return $salt;
}

$password = "erf1377";
$iterations = 320000; // 和Django默认PBKDF2迭代次数一致
$salt = generateSecureSalt($saltLen);
// 最后一个参数传true,获取原始二进制哈希结果
$rawHash = hash_pbkdf2("sha256", $password, $salt, $iterations, 0, true);
// base64编码后去除末尾的=填充符
$b64Hash = rtrim(base64_encode($rawHash), '=');
$finalHash = sprintf("pbkdf2_sha256$%d$%s$%s", $iterations, $salt, $b64Hash);

echo $finalHash;
效果说明

上述代码生成的哈希串完全符合Djangopbkdf2_sha256哈希器的格式要求,可直接存入用户表的password字段,Django内置的check_password方法可以正常完成密码校验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.31 06:12:21