Мне нужно было сделать почти то же самое для миграции. И рекомендуемый migration article предлагает решение вашей проблемы.
Вам необходимо объединить старый хэш с солью в одно поле Password
, разделенное специальным символом (в статье было |
, но вы можете выбрать свой собственный разделитель).
И тогда PasswordHasher
должен проверить пароль для этого специального символа, и если он содержит отдельную соль с паролем и применяет хеширование.
Вот фрагмент кода из связанной выше статьи, хотя я удалил некоторый шум для проверки хранилища паролей с открытым текстом. Это предполагает, что ваш хэш хранится в формате SH1hash|salt
public class SQLPasswordHasher : PasswordHasher
{
public override string HashPassword(string password)
{
return base.HashPassword(password);
}
public override PasswordVerificationResult VerifyHashedPassword(string hashedPassword, string providedPassword)
{
string[] passwordProperties = hashedPassword.Split('|');
if (passwordProperties.Length != 2)
{
// use default Identity implementation
return base.VerifyHashedPassword(hashedPassword, providedPassword);
}
else
{
string passwordHash = passwordProperties[0];
string salt = passwordProperties[1];
if (String.Equals(EncryptPassword(providedPassword, salt), passwordHash, StringComparison.CurrentCultureIgnoreCase))
{
return PasswordVerificationResult.SuccessRehashNeeded;
}
else
{
return PasswordVerificationResult.Failed;
}
}
}
//This is copied from the existing SQL provider
private string EncryptPassword(string pass, string salt)
{
byte[] bIn = Encoding.Unicode.GetBytes(pass);
byte[] bSalt = Convert.FromBase64String(salt);
byte[] bRet = null;
HashAlgorithm hm = HashAlgorithm.Create("SHA1");
if (hm is KeyedHashAlgorithm)
{
KeyedHashAlgorithm kha = (KeyedHashAlgorithm)hm;
if (kha.Key.Length == bSalt.Length)
{
kha.Key = bSalt;
}
else if (kha.Key.Length < bSalt.Length)
{
byte[] bKey = new byte[kha.Key.Length];
Buffer.BlockCopy(bSalt, 0, bKey, 0, bKey.Length);
kha.Key = bKey;
}
else
{
byte[] bKey = new byte[kha.Key.Length];
for (int iter = 0; iter < bKey.Length;)
{
int len = Math.Min(bSalt.Length, bKey.Length - iter);
Buffer.BlockCopy(bSalt, 0, bKey, iter, len);
iter += len;
}
kha.Key = bKey;
}
bRet = kha.ComputeHash(bIn);
}
else
{
byte[] bAll = new byte[bSalt.Length + bIn.Length];
Buffer.BlockCopy(bSalt, 0, bAll, 0, bSalt.Length);
Buffer.BlockCopy(bIn, 0, bAll, bSalt.Length, bIn.Length);
bRet = hm.ComputeHash(bAll);
}
return Convert.ToBase64String(bRet);
}
}
Так что вам нужно передать пароль и соль 'IPasswordHasher'? Можете ли вы изменить структуру БД? – trailmax