根据位于
https://github.com/aspnet/Identity/blob/a8ba99bc5b11c5c48fc31b9b0532c0d6791efdc8/src/Microsoft.AspNetCore.Identity/PasswordHasher.cs的文档。
曾经,身份验证使用了不同的哈希算法 - 可能在某个时候它在其中一个版本中使用了版本2格式,在另一个版本中使用了版本3格式?
该类的构造函数接受选项参数,您可以尝试调整以获取正确的哈希值?
public PasswordHasher(IOptions<PasswordHasherOptions> optionsAccessor = null)
编辑:
我在这里找到了2.0版的身份源代码:https://aspnetidentity.codeplex.com/ 和 git存储库: https://git01.codeplex.com/aspnetidentity
查看源代码时,您会发现其哈希方法。
Crypto.HashPassword.cs
public static string HashPassword(string password)
{
if (password == null)
{
throw new ArgumentNullException("password");
}
byte[] salt;
byte[] subkey;
using (var deriveBytes = new Rfc2898DeriveBytes(password, SaltSize, PBKDF2IterCount))
{
salt = deriveBytes.Salt;
subkey = deriveBytes.GetBytes(PBKDF2SubkeyLength);
}
var outputBytes = new byte[1 + SaltSize + PBKDF2SubkeyLength];
Buffer.BlockCopy(salt, 0, outputBytes, 1, SaltSize);
Buffer.BlockCopy(subkey, 0, outputBytes, 1 + SaltSize, PBKDF2SubkeyLength);
return Convert.ToBase64String(outputBytes);
}
与 aspnet identity core 中的 v2 相比:
private static byte[] HashPasswordV2(string password, RandomNumberGenerator rng)
{
const KeyDerivationPrf Pbkdf2Prf = KeyDerivationPrf.HMACSHA1;
const int Pbkdf2IterCount = 1000;
const int Pbkdf2SubkeyLength = 256 / 8;
const int SaltSize = 128 / 8;
byte[] salt = new byte[SaltSize];
rng.GetBytes(salt);
byte[] subkey = KeyDerivation.Pbkdf2(password, salt, Pbkdf2Prf, Pbkdf2IterCount, Pbkdf2SubkeyLength);
var outputBytes = new byte[1 + SaltSize + Pbkdf2SubkeyLength];
outputBytes[0] = 0x00;
Buffer.BlockCopy(salt, 0, outputBytes, 1, SaltSize);
Buffer.BlockCopy(subkey, 0, outputBytes, 1 + SaltSize, Pbkdf2SubkeyLength);
return outputBytes;
}
身份验证 v2 哈希和身份验证核心 v2 哈希看起来非常相似,现在与身份验证核心 v3 哈希进行比较:
private static byte[] HashPasswordV3(string password, RandomNumberGenerator rng, KeyDerivationPrf prf, int iterCount, int saltSize, int numBytesRequested)
{
byte[] salt = new byte[saltSize];
rng.GetBytes(salt);
byte[] subkey = KeyDerivation.Pbkdf2(password, salt, prf, iterCount, numBytesRequested);
var outputBytes = new byte[13 + salt.Length + subkey.Length];
outputBytes[0] = 0x01;
WriteNetworkByteOrder(outputBytes, 1, (uint)prf);
WriteNetworkByteOrder(outputBytes, 5, (uint)iterCount);
WriteNetworkByteOrder(outputBytes, 9, (uint)saltSize);
Buffer.BlockCopy(salt, 0, outputBytes, 13, salt.Length);
Buffer.BlockCopy(subkey, 0, outputBytes, 13 + saltSize, subkey.Length);
return outputBytes;
}
我不会假装理解这些方法的具体实现,但是从身份验证v2和身份验证核心来看,我们从无参数构造函数转换为带有配置选项的构造函数。V2使用SHA1,V3使用SHA256(等等其他方法)。
似乎身份验证核心默认使用V3方法进行哈希,而在旧版本的身份验证中不存在该方法 - 这可能是您问题的原因。
https://github.com/aspnet/Identity/blob/a8ba99bc5b11c5c48fc31b9b0532c0d6791efdc8/src/Microsoft.AspNetCore.Identity/PasswordHasherOptions.cs
在上述源代码中,V3被用作默认值。
public PasswordHasherCompatibilityMode CompatibilityMode { get; set; } = PasswordHasherCompatibilityMode.IdentityV3;
很不幸,这意味着在 identity core 中哈希的密码无法在旧版本的 identity 中使用相同的哈希方法进行哈希,因为旧方法没有被实现。也许您可以创建自己的方法来模拟 v3 中所做的操作?