AzerothCore服务器SRP6注册脚本无法生成有效salt与verifier
AzerothCore SRP6注册脚本修复方案
问题诊断
你的脚本存在几个核心问题,导致salt和verifier无法正确生成并写入数据库:
- 未调用
SRP6::getRegistrationData()方法生成salt和verifier,变量$salt、$verifier未被赋值,插入数据库时会被视为空值,最终存储为全0的二进制数据 - 直接拼接SQL语句存在严重的SQL注入风险,且无法正确处理二进制类型的字段
- 缺少密码重复验证的逻辑,无法确保两次输入的密码一致
修正后的完整代码
<?php // URL示例: // http://IP.IP.IP.IP/reg/forum-register.php?name=test&mail=tet@test.de&pass=1234567&pass-rep=1234567 // 数据库连接配置 $host = "127.0.0.1"; // 数据库主机 $user = "user"; // 数据库用户名 $pass = "pwd"; // 数据库密码 $dbName = "acore_auth"; // 数据库名称 // 建立数据库连接 $db = mysqli_connect($host, $user, $pass, $dbName); if (!$db) { exit("连接错误: " . mysqli_connect_error()); } else { echo "数据库连接成功<br><br>"; } // 获取URL参数 $username = isset($_GET['name']) ? $_GET['name'] : 'anonymous'; $email = isset($_GET['mail']) ? $_GET['mail'] : 'anonymous@xx.xx'; $password = isset($_GET['pass']) ? $_GET['pass'] : 'pwd'; $passwordRepeat = isset($_GET['pass-rep']) ? $_GET['pass-rep'] : 'pwd-rep'; // 输出参数信息 echo "用户: " . $username . "<br>"; echo "邮箱: " . $email . "<br>"; echo "密码: " . $password . "<br>"; echo "重复密码: " . $passwordRepeat . "<br><br>"; // 密码一致性验证 if ($password !== $passwordRepeat) { exit("错误: 两次输入的密码不一致"); } class SRP6 { // 基于TrinityCore账号生成器的SRP6实现 public static function calculateSRP6Verifier($username, $password, $salt) { // SRP6算法常量 $g = gmp_init(7); $N = gmp_init('894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7', 16); // 计算第一个哈希值(用户名:密码,大写后SHA1) $h1 = sha1(strtoupper($username . ':' . $password), TRUE); // 计算第二个哈希值(salt + h1的SHA1) $h2 = sha1($salt . $h1, TRUE); // 将二进制哈希转换为小端序整数 $h2 = gmp_import($h2, 1, GMP_LSW_FIRST); // 计算g^h2 mod N $verifier = gmp_powm($g, $h2, $N); // 将整数转换回小端序二进制数组 $verifier = gmp_export($verifier, 1, GMP_LSW_FIRST); // 填充至32字节(小端序,补零在末尾) $verifier = str_pad($verifier, 32, chr(0), STR_PAD_RIGHT); return $verifier; } public static function getRegistrationData($username, $password) { // 生成32字节随机salt $salt = random_bytes(32); // 使用生成的salt计算verifier $verifier = self::calculateSRP6Verifier($username, $password, $salt); return [$salt, $verifier]; } } // 调用SRP6方法生成salt和verifier list($salt, $verifier) = SRP6::getRegistrationData($username, $password); // 使用预处理语句插入数据库(避免SQL注入,正确处理二进制数据) $stmt = mysqli_prepare($db, "INSERT INTO `account` (username, email, salt, verifier) VALUES (?, ?, ?, ?)"); mysqli_stmt_bind_param($stmt, "ssbb", $username, $email, $salt, $verifier); if (mysqli_stmt_execute($stmt)) { echo "账号注册成功,已写入数据库"; } else { echo "插入数据库失败: " . mysqli_stmt_error($stmt); } // 关闭语句和连接 mysqli_stmt_close($stmt); mysqli_close($db); ?>
关键修改说明
- 调用SRP6生成方法:新增
list($salt, $verifier) = SRP6::getRegistrationData($username, $password);,实际触发salt和verifier的生成逻辑,这是原脚本最核心的缺失步骤 - 密码一致性验证:添加
if ($password !== $passwordRepeat)判断,确保用户两次输入的密码一致,避免无效注册 - 使用预处理语句:替换直接拼接SQL的方式,用
mysqli_prepare和mysqli_stmt_bind_param处理插入操作,绑定参数类型ssbb分别对应字符串、字符串、二进制、二进制,彻底避免SQL注入风险,同时确保二进制数据正确写入数据库 - 完善资源释放:新增关闭预处理语句和数据库连接的代码,符合PHP最佳实践
内容的提问来源于stack exchange,提问作者Corelith
相关产品推荐
相关产品推荐

