如何修改或移除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
相关产品推荐
相关产品推荐

