使用VB.NET+SRP6实现魔兽世界账号注册的密码验证问题求助
《魔兽世界》账号注册密码验证问题修复
核心问题排查
- SQL参数绑定错误:原代码中SQL语句的第三个字段是
salt,但参数误用了@pass,还错误地在加密关闭时传入明文密码——AzerothCore的account表采用SRP6验证机制,仅需存储salt和verifier,不需要明文密码。 - SRP6算法BigInteger处理缺陷:字节数组转BigInteger时未处理符号位问题,导致计算出的verifier不符合游戏端验证规则。
修复后的代码
1. RegisterUser方法修复
Public Sub RegisterUser() Dim conStr = "Server=" + Data.Settings.MySQLServerHost + ";Uid=" + Data.Settings.MySQLServerUser + ";Database=" + Data.Settings.AuthDatabase + ";Port=" + Data.Settings.MySQLServerPort + ";Pwd=" + Data.Settings.MySQLServerPassword + ";" Dim salt(31) As Byte Using rng As New RNGCryptoServiceProvider() rng.GetBytes(salt) End Using ' 计算SRP6验证值 Dim verifier As Byte() = SRP6.CalculateSRP6Verifier(TextAccountCreateName.Text, TextAccountPasswordCreate.Text, salt) Try Using conn As New MySqlConnection(conStr) Using cmd As New MySqlCommand() cmd.Connection = conn Select Case Data.Settings.SelectedCore Case Cores.AzerothCore ' 修正参数与字段的对应关系,移除错误的明文密码逻辑 cmd.CommandText = "INSERT INTO account (username, email, salt, verifier) VALUES (@user,@ema,@salt,@verif)" cmd.Parameters.AddWithValue("@user", TextAccountCreateName.Text.ToUpper()) ' 强制存储大写用户名 cmd.Parameters.AddWithValue("@ema", TextAccountEmailCreate.Text) cmd.Parameters.AddWithValue("@salt", salt) cmd.Parameters.AddWithValue("@verif", verifier) Case Else Exit Sub End Select conn.Open() cmd.ExecuteNonQuery() End Using End Using Catch ex As Exception MsgBox(ex.Message) End Try End Sub
2. SRP6类修复
Imports System.Security.Cryptography Imports System.Numerics Public Class SRP6 Public Shared Function CalculateSRP6Verifier(ByVal username As String, ByVal password As String, ByVal salt As Byte()) As Byte() ' AzerothCore标准SRP6常量 Dim g As BigInteger = 7 Dim N As BigInteger = BigInteger.Parse("894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7", Globalization.NumberStyles.HexNumber) ' 1. 计算H1 = SHA1(大写用户名:大写密码) Dim h1 As Byte() = SHA1.Create().ComputeHash(Text.Encoding.UTF8.GetBytes(username.ToUpper() & ":" & password.ToUpper())) ' 2. 计算H2 = SHA1(salt + H1) Dim h2 As Byte() = SHA1.Create().ComputeHash(salt.Concat(h1).ToArray()) ' 3. 将H2转为无符号BigInteger(添加0字节避免符号位干扰) Dim h2Bytes = h2.Reverse().Concat({CByte(0)}).ToArray() Dim h2Int As New BigInteger(h2Bytes) ' 4. 计算verifier = g^H2 mod N Dim verifier As BigInteger = BigInteger.ModPow(g, h2Int, N) ' 5. 将verifier转为32字节大端格式(匹配AzerothCore存储要求) Dim verifierBytes = verifier.ToByteArray() ' 移除可能存在的符号位字节 If verifierBytes.Length > 32 Then Array.Resize(verifierBytes, 32) End If ' 反转并补全到32字节 verifierBytes = verifierBytes.Reverse().ToArray() If verifierBytes.Length < 32 Then Array.Resize(verifierBytes, 32) End If Return verifierBytes End Function End Class
关键修复说明
- 用户名强制大写:按照数据库规则将用户名转为大写后存储,确保与游戏端验证逻辑一致。
- 修正SQL参数映射:将
salt字段与@salt参数正确绑定,彻底移除明文密码存储逻辑,符合SRP6的安全设计。 - BigInteger符号位处理:转换字节数组时添加额外0字节,避免BigInteger将最高位识别为符号位导致计算错误;同时保证最终verifier为32字节大端格式,匹配AzerothCore的存储规则。
内容的提问来源于stack exchange,提问作者Evolution-Team
相关产品推荐
相关产品推荐

