Asp.net хеширование паролей

Новый проект ASP.net Identity принес несколько полезных кодов и интерфейсов для безопасности сайта. Для реализации пользовательской системы с использованием интерфейсов (вместо использования стандартной реализации Entity Framework, включенной в шаблон MVC 5) IPasswordHasher необходимо.

IPasswordHasher интерфейс в ASP.net идентичности

namespace Microsoft.AspNet.Identity
{
    public interface IPasswordHasher
    {
         string HashPassword(string password);
         PasswordVerificationResult VerifyHashedPassword(string hashedPassword, string providedPassword);
    }
}

Можно ли использовать соляризацию паролей для более безопасного шифрования в ASP.net Identity и через этот интерфейс?

3 ответа

Решение

"Можно ли использовать соляризацию паролей для более безопасного шифрования в ASP.net Identity и через этот интерфейс?"

Да, интерфейс предоставляется для новой реализации PasswordHasher, уже присутствующей в платформе Core.

Также обратите внимание, что реализация по умолчанию уже использует Salt+Bytes.

После создания кастома PasswordHasher (сказать MyPasswordHasher), вы можете назначить его экземпляру UserManager как userManager.PasswordHasher=new MyPasswordHasher()

Смотрите один пример такого IPasswordHasher

Для реализации пользовательской системы с использованием интерфейсов (вместо использования стандартной реализации Entity Framework, включенной в шаблон MVC 5) требуется IPasswordHasher.

Для реализации альтернативной системы от EF, Вы должны реализовать все Базовые интерфейсы. - Реализация IPasswordHasher не требуется. PasswordHasher уже предоставляется в Core Framework в качестве его реализации.

ВНИМАНИЕ ЗДОРОВЬЯ для ответа ниже: Знайте, какую версию ASP.Net Identity вы используете. Вы должны обращаться к исходному коду напрямую, если это одна из более новых версий из репозитория github.

На момент написания этой статьи текущая версия обработчика паролей ( 3.0.0-rc1 /.../ PasswordHasher.cs) значительно отличается от приведенного ниже ответа. Эта более новая версия поддерживает несколько версий алгоритма хеширования и задокументирована как (и может измениться к тому времени, когда вы прочитаете это):

Версия 2:

  • PBKDF2 с HMAC-SHA1, 128-битная соль, 256-битный подключ, 1000 итераций.
  • (См. Также: SDL Crypto Guide v5.1, часть III)
  • Формат: { 0x00, salt, subkey }

Версия 3:

  • PBKDF2 с HMAC-SHA256, 128-битная соль, 256-битный подключ, 10000 итераций.
  • Формат: { 0x01, prf (UInt32), iter count (UInt32), salt length (UInt32), salt, subkey }
  • (Все UInt32 хранятся с прямым порядком байтов.)

Оригинальный ответ по-прежнему действителен для исходной версии ASP.Net Identity и выглядит следующим образом:


@ jd4u правильно, но пролить немного больше света, который не вписался бы в комментарий к его ответу:

  • Microsoft.AspNet.Identity.PasswordHasher : IPasswordHasher уже соли для тебя,
  • По умолчанию Microsoft.AspNet.Identity.UserManager<TUser> реализация использует Microsoft.AspNet.Identity.PasswordHasher как бетон IPasswordHasher
  • PasswordHasher в свою очередь это действительно простая оболочка для (в конечном итоге) System.Security.Cryptography.Rfc2898DeriveBytes

Итак, если вы собираетесь использовать Rfc2898DeriveBytes Просто используйте PasswordHasher - все тяжелые работы уже сделаны (надеюсь, правильно) для вас.

подробности

Полный код, который в конечном итоге использует PasswordHasher, делает что-то очень похожее на:

int saltSize = 16;
int bytesRequired = 32;
byte[] array = new byte[1 + saltSize + bytesRequired];
int iterations = SOME; // 1000, afaik, which is the min recommended for Rfc2898DeriveBytes
using (var pbkdf2 = new Rfc2898DeriveBytes(password, saltSize, iterations))
{
    byte[] salt = pbkdf2.Salt;        
    Buffer.BlockCopy(salt, 0, array, 1, saltSize);
    byte[] bytes = pbkdf2.GetBytes(bytesRequired);
    Buffer.BlockCopy(bytes, 0, array, saltSize+1, bytesRequired);
}
return Convert.ToBase64String(array);

Я столкнулся с проблемой при обновлении от членства до AspNet.Identity. Хеши Rfc2898 отличаются от тех, которые использовались ранее. Это не зря, но для изменения хешей всем пользователям потребуется сбросить свои пароли. В качестве решения эта пользовательская реализация делает его обратно совместимым:

public class MyPasswordHasher : PasswordHasher {

   public FormsAuthPasswordFormat FormsAuthPasswordFormat { get; set; }

   public MyPasswordHasher(FormsAuthPasswordFormat format) {
      FormsAuthPasswordFormat = format;
   }

   public override string HashPassword(string password) {
      return FormsAuthentication.HashPasswordForStoringInConfigFile(password, FormsAuthPasswordFormat.ToString());
   }

   public override PasswordVerificationResult VerifyHashedPassword(string hashedPassword, string providedPassword) {
     var testHash = FormsAuthentication.HashPasswordForStoringInConfigFile(providedPassword, FormsAuthPasswordFormat.ToString());
     return hashedPassword.Equals(testHash) ? PasswordVerificationResult.Success : PasswordVerificationResult.Failed;
   }
}

Как только вы создадите свой экземпляр UserManager, просто установите хеш:

Usermanager.PasswordHasher = new MyPasswordHasher(FormsAuthPasswordFormat.SHA1);

Код жалуется, что HashPasswordForStoringInConfigFile метод устарел, но это прекрасно, так как мы знаем, что все упражнение состоит в том, чтобы избавиться от старой технологии.

Другие вопросы по тегам