TrinityCore 弃用了 auth 表上的旧 sha_pass_hash 列,转而采用更安全的 SRP6 方法。但是,我无法使用此处提供的示例正确计算 PHP 中 C#/dotnet NOR 中的验证程序。我查看了示例,但它似乎不像 TrinityCore 开发人员建议的那样工作。有谁知道 SRP6 可能能够找出代码中的问题?我也看过这个例子,但它使用了硬编码的盐?如果有人可以告诉我 PHP 有什么问题,我也许可以弄清楚 .NET 有什么问题
我尝试的代码看起来最接近第一个示例,但我将数组翻转为小端。
public byte[] CalculateVerifier(string username, string password, byte[] salt)
{
if (BitConverter.IsLittleEndian)
{
return BigInteger.ModPow(
g,
new BigInteger(Hash(salt, Hash(Encoding.UTF8.GetBytes($"{username.ToUpper()}:{password.ToUpper()}")))),
N
).ToByteArray();
}
else
{
return BigInteger.ModPow(
g,
new BigInteger(Hash(salt, Hash(Encoding.UTF8.GetBytes($"{username.ToUpper()}:{password.ToUpper()}")).Reverse().ToArray())),
N
).ToByteArray();
}
}
public bool VerifySRP6Login(string username, string password, byte[] salt, byte[] verifier)
{
// re-calculate the verifier using the provided username + password and the stored salt
byte[] checkVerifier = CalculateSRP6Verifier(username, password, salt);
Console.WriteLine($"{Encoding.ASCII.GetString(verifier)} {verifier.Length} bytes\n{Encoding.ASCII.GetString(checkVerifier)} {checkVerifier.Length} bytes");
Console.WriteLine($"{new BigInteger(verifier)}\n{new BigInteger(checkVerifier)}");
// compare it against the stored verifier
return verifier.SequenceEqual(checkVerifier);
}
public byte[] Hash(byte[] componentOne, byte[] componentTwo)
{
if (componentOne == null) throw new ArgumentNullException(nameof(componentOne));
if (componentTwo == null) throw new ArgumentNullException(nameof(componentTwo));
//WoW expects non-secure SHA1 hashing. SRP6 is deprecated too. We need to do it anyway
using (SHA1 shaProvider = SHA1.Create())
{
//See Jackpoz's Combine function
return shaProvider.ComputeHash(componentOne.Concat(componentTwo).ToArray());
}
}
public byte[] Hash(byte[] bytes)
{
if (bytes == null) throw new ArgumentNullException(nameof(bytes));
//WoW expects non-secure SHA1 hashing. SRP6 is deprecated too. We need to do it anyway
using (SHA1 shaProvider = SHA1.Create())
{
return shaProvider.ComputeHash(bytes);
}
}