2015-05-08 2 views
1

Я пытаюсь переключиться на .NET Identity из старого поставщика пользовательского членства в существующем приложении MVC и поддерживать dapper как ORM, а не EntityFramework, который выходит из коробки..NET Identity 2.0 с пользовательскими соленными паролями

Я застрял в попытке реализовать свои собственные IPasswordHasher, так как мне нужны существующие учетные данные для работы. В HashPassword Я хочу вернуть SHA-вычисленный хэш ввода cleartext в сочетании с солью, специфичной для пользователя, но метод получает только чистое текстовое значение и не ссылается на пользователя, для которого выполняется попытка входа в систему.

Где я могу получить эту соль? Или я иду на это не так?

+0

Так что вам нужно передать пароль и соль 'IPasswordHasher'? Можете ли вы изменить структуру БД? – trailmax

ответ

2

Мне нужно было сделать почти то же самое для миграции. И рекомендуемый 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); 
    } 
} 
+1

Спасибо. Я закончил тем, что почти идентично этому (в настоящее время выполняется хеш + соль concat в 'UserStore.GetPasswordHashAsync', если длина хэша пароля соответствует моим старым хэшам), но это тоже очень удобно. Я могу переключиться на выполнение concat непосредственно в базе данных, как только мы выйдем вживую, чтобы я мог немедленно избавиться от поля Salt. –

Смежные вопросы