Проверка работоспособности: соль и хешированные пароли - PullRequest
5 голосов
/ 28 июля 2010

У меня была идея о хешированных паролях и солт-значениях.Так как я довольно новичок в хешировании и шифровании, я решил опубликовать это для вас.Будет ли безопаснее генерировать уникальную соль для каждой учетной записи пользователя, а затем хранить значения соли и хэшированные значения в базе данных?Или хранить безопасное единственное значение соли и повторно использовать его каждый раз, когда я хэширую пароль?

Например, пользователь будет использовать пароль:

"secret"

Мой код сгенерируетзначение соли:

"d1d0e3d4b3d1ed1598a4e77bb614750a2a175e"

Затем хэшируйте результат, чтобы получить:

"e8187dcbe8e2eabd4675f3a345fe21c98affb
 5544a9278461535cb67265b6fe09a11dbef572
 ce3a4a8f2275839927625cf0bc7bc46fc45d51
 12d7c0713bb4a3"

Результат хеширования и соль будут сохранены в базе данных в профиле пользователя, когда их учетная записьсоздано.Затем каждый раз, когда пользователь входит в систему, генерируется новая соль, пароль и соль перефразируются и сохраняются в базе данных.

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

Ответы [ 4 ]

7 голосов
/ 28 июля 2010

Хранение уникальной соли на пользователя - хорошая идея, на мой взгляд.Повторно генерировать комбинацию соль / хэш каждый раз, когда пользователь входит в систему, немного бессмысленно, если у вас нет циклов ЦП для записи.Я бы порекомендовал использовать что-то вроде Rfc2898DeriveBytes класса для генерации безопасного комбо соли / хэша:

Простой пример генерации хэша из пароля:

string password = GetPasswordFromInput();

using (var deriveBytes = new Rfc2898DeriveBytes(password, 32))  // 32-byte salt
{
    byte[] salt = deriveBytes.Salt;
    byte[] hash = deriveBytes.GetBytes(32);  // 32-byte hash
    SaveToDatabase(salt, hash);
}

и соответствующая проверка пароля:

string password = GetPasswordFromInput();
byte[] salt = GetSaltFromDatabase();
byte[] hash = GetHashFromDatabase();

using (var deriveBytes = new Rfc2898DeriveBytes(password, salt))
{
    if (deriveBytes.GetBytes(32).SequenceEqual(hash))
        Console.WriteLine("Password matches");
    else
        throw new Exception("Bad password");
}
5 голосов
/ 28 июля 2010

Как уже упоминал Адам, хеширование и хранение пароля каждый раз, когда пользователь входит в систему, не имеет никакой реальной цели.

Вместо того, чтобы переходить самостоятельно, вы можете захотеть использовать BCrypt.NET , .NET-реализация проверенного алгоритма хеширования паролей.

Использование очень просто:

// When setting password
string hashedPassword = BCrypt.HashPassword(password, BCrypt.GenerateSalt());

// Upon login
bool validPassword = BCrypt.CheckPassword(password, hashedPassword);

Позволяет варьировать вычислительные затраты на вычисление хэша пароля, если вам это нужно, что затрудняет атаку по словарюнапример, базу данных, которую они могли бы получить.Это делается путем добавления параметра к вызову метода GenerateSalt.

Подробности алгоритма BCrypt можно найти здесь .

3 голосов
/ 28 июля 2010
  • У каждого пользователя должна быть своя уникальная соль.
  • Нет смысла обновлять соль каждый раз, когда пользователь входит в систему, это не имеет смысла с точки зрения безопасности.
  • Соль должна генерироваться случайным образом и никоим образом не связываться с паролем.

Цель соли - защитить от атак до вычислений (таких как радужные таблицы),Таким образом, если два пользователя имеют одинаковый пароль, они не будут иметь одинаковый окончательный хэш.Если соль распространяется на всю систему, а не на пользователя, то это не так, и злоумышленнику нужно только предварительно рассчитать все пароли для вашей системы.Если у каждого пользователя есть своя собственная соль, то для каждого пользователя должна быть проведена атака перед вычислением, что делает эту атаку неосуществимой.

Использование соленого хэша не защищает от атак методом перебора словаря.Вам нужно будет использовать другие методы для защиты от них.

1 голос
/ 28 июля 2010

Настоящей целью соли является предотвращение атак до вычислений, поскольку сама соль НЕ должна быть секретной (то есть хорошо, чтобы она была доступна из внешнего мира).Поэтому он не предназначен для обеспечения защиты от перебора, поскольку его (почти) так же легко хешировать (Salt + Password), как и хеш-код (Password).

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

...