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

如何修改或移除XenForo 2.2.13的PasswordHash类以更换加密算法?

XenForo 2.2.13 修改PasswordHash类更换/移除加密算法

问题背景

我正在使用XenForo [2.2.13]版本。当前PasswordHash类通过自定义算法处理密码的生成与验证,我希望修改该类来更换或移除加密算法,但不清楚具体操作方法,恳请提供帮助。

当前核心代码片段

function gensalt_blowfish($input)
{
    # This one needs to use a different order of characters and a
    # different encoding scheme from the one in encode64() above.
    # We care because the last character in our encoded string will
    # only represent 2 bits.  While two known implementations of
    # bcrypt will happily accept and correct a salt string which
    # has the 4 unused bits set to non-zero, we do not want to take
    # chances and we also do not want to waste an additional byte
    # of entropy.
    $itoa64 = './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';

    $output = '$2a$';
    $output .= chr(ord('0') + $this->iteration_count_log2 / 10);
    $output .= chr(ord('0') + $this->iteration_count_log2 % 10);
    $output .= '$';

    $i = 0;
    do {
        $c1 = ord($input[$i++]);
        $output .= $itoa64[$c1 >> 2];
        $c1 = ($c1 & 0x03) << 4;
        if ($i >= 16) {
            $output .= $itoa64[$c1];
            break;
        }

        $c2 = ord($input[$i++]);
        $c1 |= $c2 >> 4;
        $output .= $itoa64[$c1];
        $c1 = ($c2 & 0x0f) << 2;

        $c2 = ord($input[$i++]);
        $c1 |= $c2 >> 6;
        $output .= $itoa64[$c1];
        $output .= $itoa64[$c2 & 0x3f];
    } while (1);

    return $output;
}
function HashPassword($password) { $random = '';

    if (CRYPT_BLOWFISH == 1 && !$this->portable_hashes) {
        $random = $this->get_random_bytes(16);
        $hash = $this->gensalt_blowfish($random);
        return $this->crypt_private($password, $hash);
    }

    if (CRYPT_EXT_DES == 1 && !$this->portable_hashes) {
        $random = $this->get_random_bytes(3);
        $hash = $this->gensalt_extended($random);
        return $this->crypt_private($password, $hash);
    }

    $random = $this->get_random_bytes(6);
    $hash = $this->gensalt_private($random);

    return $this->crypt_private($password, $hash);
}
function CheckPassword($password, $stored_hash) { $hash = $this->crypt_private($password, $stored_hash);

    return hash_equals($stored_hash, $hash);
}

public function reverseItoA64($char)
{
    return strpos($this->itoa64, $char);
}
}

解决方案

注意事项

直接修改XenForo核心文件会导致后续升级困难,优先推荐使用XenForo的扩展系统重写PasswordHash类,而非直接修改核心代码。


方案1:更换为Argon2加密算法

Argon2是PHP 7.2+支持的现代加密算法,安全性高于bcrypt。以下是重写PasswordHash类的核心逻辑:

class YourCustomPasswordHash extends \XenForo_PasswordHash
{
    public function HashPassword($password)
    {
        // 使用PHP原生函数生成Argon2ID哈希
        return password_hash($password, PASSWORD_ARGON2ID);
    }

    public function CheckPassword($password, $stored_hash)
    {
        // 兼容旧哈希:原系统bcrypt/ext_des哈希用父类方法验证
        if (str_starts_with($stored_hash, '$2a$') || str_starts_with($stored_hash, '$1$')) {
            return parent::CheckPassword($password, $stored_hash);
        }
        // 新哈希用原生函数验证
        return password_verify($password, $stored_hash);
    }

    // 原salt生成方法可保留(兼容旧逻辑)或直接置空
    public function gensalt_blowfish($input) {}
    public function gensalt_extended($input) {}
    public function gensalt_private($input) {}
}

接着在自定义插件的Listener.php中添加依赖注入覆盖:

public static function loadClass($class, &$extend)
{
    if ($class == 'XenForo_PasswordHash') {
        $extend[] = 'YourAddOn_YourCustomPasswordHash';
    }
}

方案2:完全移除自定义算法,改用PHP原生密码函数

如果不需要保留任何自定义加密逻辑,直接替换核心方法:

class YourCustomPasswordHash extends \XenForo_PasswordHash
{
    public function HashPassword($password)
    {
        // 可自定义Argon2参数,调整内存占用、迭代次数等
        $options = [
            'memory_cost' => 1<<17, // 128MB
            'time_cost' => 4,
            'threads' => 2
        ];
        return password_hash($password, PASSWORD_ARGON2ID, $options);
    }

    public function CheckPassword($password, $stored_hash)
    {
        // 兼容旧哈希验证
        if (str_starts_with($stored_hash, '$2a$') || str_starts_with($stored_hash, '$1$')) {
            $hash = $this->crypt_private($password, $stored_hash);
            return hash_equals($stored_hash, $hash);
        }
        return password_verify($password, $stored_hash);
    }
}

直接修改核心文件(不推荐)

若必须直接修改核心类(路径:library/XenForo/PasswordHash.php),替换HashPassword和CheckPassword方法:

function HashPassword($password)
{
    return password_hash($password, PASSWORD_ARGON2ID);
}

function CheckPassword($password, $stored_hash)
{
    // 兼容旧哈希
    if (str_starts_with($stored_hash, '$2a$') || str_starts_with($stored_hash, '$1$')) {
        $hash = $this->crypt_private($password, $stored_hash);
        return hash_equals($stored_hash, $hash);
    }
    return password_verify($password, $stored_hash);
}

警告:直接修改核心文件会导致升级时代码被覆盖,每次升级都需要重新修改,风险较高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 04:24:53