Подтвердить что ты не робот

System.Web.Helpers.Crypto - Где соль?

В прошлом при работе с паролями я всегда хранил соль и хешированный пароль отдельно в своем хранилище данных. Сегодня я искал обновление устаревшего кода для использования хеш-значения RFC 2898. Я наткнулся на методы Crypto.Hash от System.Web.Helpers. Похоже, что они сделают большую часть тяжелой работы для меня. Существуют методы GenerateSalt(), HashPassword() и VerifyHashedPassword(). Методы HashPassword() и VerifyHashedPassword() не принимают значение соли. Документация MSDN для метода HashPassword() гласит:

"Формат генерируемого хэш-потока - {0x00, соль, подраздел}, который кодируется base-64, прежде чем он будет возвращен."

Нужно ли беспокоиться о соли? В документации, по-видимому, говорится, что соль будет генерироваться автоматически и храниться в кодированном значении base-64? Это верно? Все, что мне нужно сохранить, это строка, возвращаемая из HashPassword()?

4b9b3361

Ответ 1

Ответ

Все пароли должны быть солеными, чтобы безопасно их использовать. В этом случае, однако, вы правы. System.Web.Helpers.Crypto заботится о создании соли для вас. Вам не нужно его создавать. Он сохраняется в строке, возвращаемой Crypto.HashPassword().

Пример

Все, что вам нужно сделать, это что-то вроде этого.

using System.Web.Helpers;

public void SavePassword(string unhashedPassword)
{
    string hashedPassword = Crypto.HashPassword(unhashedPassword);
    //Save hashedPassword somewhere that you can retrieve it again.
    //Don't save unhashedPassword! Just let it go.
}

public bool CheckPassword(string unhashedPassword)
{
    string savedHashedPassword = //get hashedPassword from where you saved it

    return Crypto.VerifyHashedPassword(savedHashedPassword, unhashedPassword)
}

Дополнительная информация

  • Если вы хотите увидеть исходный код для класса Crypto, вы можете его просмотреть здесь.
  • И здесь - хороший блог по классу и некоторые из его идей.

Ответ 2

Просто хотел поделиться этим сообщением:

http://forums.asp.net/t/1842429.aspx?System+Web+Helpers+Crypto+HashPassword

Здравствуйте,
Я смотрел новый метод Crypto HashPassword и VerifyMethod в System.Web.Helpers.
Оба метода используют соль, но они не возвращают Соль только Хешу.
Не нужна ли мне соль для ее хранения в базе данных? Я что-то не хватает?
Спасибо,
Miguel

..

Вы создадите соль, когда пользователь создаст учетную запись, а затем вы должны добавить его к паролю, прежде чем вызывать HashPassword. Вы хотите затем сохраните эту соль и хешированный пароль в вашей БД. Когда ты проверьте учетные данные, просто прочитайте соль из БД и добавьте ее в пароль от входа в систему перед вызовом VerifyHashedPassword. BrockAllen

..

Не уверен, понял ли я это... Потому что в HashPassword соль сгенерированный внутри метода:

Мигель

// Method in Crypto class
public static string HashPassword(string password)
{
    if (password == null)
    {
        throw new ArgumentNullException("password");
    }

    // Produce a version 0 (see comment above) password hash.
    byte[] salt;
    byte[] subkey;
    using (var deriveBytes = new Rfc2898DeriveBytes(password, SaltSize, PBKDF2IterCount))
    {
        salt = deriveBytes.Salt;
        subkey = deriveBytes.GetBytes(PBKDF2SubkeyLength);
    }

    byte[] 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);
}

..

BrockAllen 11 сентября 2012 г. 19:50

Да, проигнорируйте это - это внутренняя соль для Rfc2898DeriveBytes и он получен из пароля, поэтому это не настоящая соль в контекст хранения паролей, поскольку он постоянно воссоздан для тот же пароль. Вы захотите по-прежнему делать свою соль на уровень строки пароля. Так что-то вроде этого:

public void CreateAccount(string username, string password)
{
    var salt = Crypto.GenerateSalt();
    var saltedPassword = password + salt;
    var hashedPassword = Crypto.HashPassword(saltedPassword);
    CreateAccount(username, salt, hashedPassword);
}

public void Verify(string username, string password)
{
    var salt = GetSaltForUserFromDatabase(username);
    var hashedPassword = GetHashedPasswordForUserFromDatabase(username);
    var saltedPassword = password + salt;
    if (Crypto.VerifyHashedPassword(hashedPassword, saltedPassword))
    {
        // valid password for this username
    }
}

Это позволит вам хранить соль в базе данных вместе с хешированным засоленным паролем.

Дополнительная информация о хэшировании паролей с солью в целом из этого сообщения: https://crackstation.net/hashing-security.htm

Чтобы сохранить пароль

  • Генерировать длинную случайную соль с использованием CSPRNG.
  • Подготовьте соль к паролю и установите его с помощью стандартной криптографической хэш-функции, такой как SHA256.
  • Сохраните соль и хэш в записи базы данных пользователя.

Проверка пароля

  • Извлеките пользовательскую соль и хэш из базы данных.
  • Подготовьте соль к данному паролю и используйте его с помощью той же функции хэша.
  • Сравните хэш заданного пароля с хешем из базы данных. Если они совпадают, пароль правильный. В противном случае пароль неверен.

Исходный код для класса Crypto:

http://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Helpers/Crypto.cs