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

将WordPress密码存储函数转换为Python的问题求助

WordPress密码哈希Python实现问题

三周前我在Stack Overflow上发布了一个问题,想弄清楚WordPress是怎么把密码存储到数据库里的。有人建议我去看源码,我尝试了但不太懂PHP,所以正在把相关函数转换成Python代码。以下是我目前的进展:

我的Python代码

import base64
from email.encoders import encode_base64
from hashlib import md5

prefix = '$P$B'
salt = 'KcFRBGXE'
password = '^zVw*wSFshV2' # 登录时输入的密码

real_hashed_pass = '$P$BKcFRBGXEWOVYQShBC1edT7f3e3Nca1' # WordPress数据库中存储的哈希值

hashed_pass = md5((salt + password).encode('utf-8')).hexdigest()

for i in range(8193):
    hashed_pass = md5((hashed_pass + password).encode('utf-8')).hexdigest()


# for i in range(17):
    # hashed_pass = base64.standard_b64encode(hashed_pass)

hashed_pass = prefix + salt + hashed_pass

print(hashed_pass == real_hashed_pass)

WordPress相关PHP代码

<?php

class PasswordHash {
    var $itoa64;
    var $iteration_count_log2;
    var $portable_hashes;
    var $random_state;

    function __construct($iteration_count_log2, $portable_hashes)
    {
        $this->itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';

        if ($iteration_count_log2 < 4 || $iteration_count_log2 > 31)
            $iteration_count_log2 = 8;
        $this->iteration_count_log2 = $iteration_count_log2;

        $this->portable_hashes = $portable_hashes;

        $this->random_state = microtime();
        if (function_exists('getmypid'))
            $this->random_state .= getmypid();
    }

    function encode64($input, $count)
    {
        $output = '';
        $i = 0;
        do {
            $value = ord($input[$i++]);
            $output .= $this->itoa64[$value & 0x3f];
            if ($i < $count)
                $value |= ord($input[$i]) << 8;
            $output .= $this->itoa64[($value >> 6) & 0x3f];
            if ($i++ >= $count)
                break;
            if ($i < $count)
                $value |= ord($input[$i]) << 16;
            $output .= $this->itoa64[($value >> 12) & 0x3f];
            if ($i++ >= $count)
                break;
            $output .= $this->itoa64[($value >> 18) & 0x3f];
        } while ($i < $count);

        return $output;
    }

    function crypt_private($password, $setting)
    {
        $output = '*0';
        if (substr($setting, 0, 2) === $output)
            $output = '*1';

        $id = substr($setting, 0, 3);
        # 我们用"$P$",phpBB3用"$H$"表示同样的东西
        if ($id !== '$P$' && $id !== '$H$')
            return $output;

        $count_log2 = strpos($this->itoa64, $setting[3]);
        if ($count_log2 < 7 || $count_log2 > 30)
            return $output;

        $count = 1 << $count_log2;

        $salt = substr($setting, 4, 8);
        if (strlen($salt) !== 8)
            return $output;

        # 我们不得不使用MD5,因为它是所有在用PHP版本都支持的唯一加密原语。
        # 在PHP中实现自己的底层加密会导致性能大幅下降,进而降低迭代次数,
        # 使得哈希更容易被非PHP代码破解。
        $hash = md5($salt . $password, TRUE);
        do {
            $hash = md5($hash . $password, TRUE);
        } while (--$count);

        $output = substr($setting, 0, 12);
        $output .= $this->encode64($hash, 16);

        return $output;
    }

    function CheckPassword($password, $stored_hash)
    {
        if ( strlen( $password ) > 4096 ) {
            return false;
        }

        $hash = $this->crypt_private($password, $stored_hash);
        if ($hash[0] === '*')
            $hash = crypt($password, $stored_hash);

        # 这不是恒定时间比较。为了保持代码简洁,我们目前依赖盐值的不可预测性来保证时序安全,
        # 至少在非回退情况下(即使用/dev/urandom和bcrypt时)是这样的。
        return $hash === $stored_hash;
    }
}

我的目标是让Python代码生成和WordPress代码完全一致的哈希密码。我觉得问题出在被注释掉的循环部分,但不知道该怎么修复。

感谢帮忙!


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 16:00:20