Пароли веб-приложений: bcrypt и SHA256 (и scrypt)

При всех недавних (например, LinkedIn) обсуждениях паролей я смотрю на реализации хеширования паролей. После двух чашек кофе и утреннего чтения я стал криптографом не больше, чем когда начинал. И я действительно не хочу притворяться, что я.

Конкретные вопросы

  1. Является ли использование целочисленного уникального идентификатора пользователя неэффективным? (crypt() использует только 16 бит?)

  2. Если я просто запускаю sha256() для хэша снова и снова, пока не будет израсходована секунда, побеждает ли это атаки грубой силы?

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

Обсуждение/Объяснение:

Цель состоит в том, что если бы хешированные пароли моего пользователя были утекли, их:

  1. было бы нелегко взломать,
  2. взлом одного пароля не подвергнет опасности других пользователей, использующих тот же пароль. пароль).

Что я прочитал для #1, так это то, что вычисление хеш-функции должно быть дорогим — вычисление занимает, скажем, секунду или две и, возможно, требует бита или памяти (чтобы помешать аппаратному дешифрованию).

В bcrypt это встроено, а scrypt, если я правильно понимаю, более перспективен и требует минимального использования памяти.

Но не менее ли эффективен подход к съедению времени путем «перефразирования» результата sha256() столько раз, сколько необходимо для использования нескольких секунд, а затем сохранения конечного количества циклов с хэшем для последующей проверки предоставленного пароль?

Для № 2 важно использовать уникальную соль для каждого пароля. Что было неясно, так это то, насколько случайной (или большой) должна быть соль. Если цель состоит в том, чтобы избежать того, чтобы все, кто использует «mypassword» в качестве своего пароля, имели один и тот же хэш, разве недостаточно просто сделать это?:

hash = sha256_hex( unique_user_id + user_supplied_password );

или даже это, хотя я не уверен, что это что-то купит:

hash = sha256_hex( sha256( unique_user_id ) + user_supplied_password );

Единственное преимущество, которое я вижу в использовании идентификатора пользователя, помимо того, что я знаю, что он уникален, — это отсутствие необходимости сохранять соль вместе с хэшем. Не большое преимущество. Есть ли реальная проблема с использованием идентификатора пользователя в качестве соли? Разве это не соответствует пункту 2?

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

# app_wide_string = one-time generated, random 64 7-bit *character* string.
hash = sha256_hex( unique_user_id + app_wide_string + user_supplied_password );

Я видел это предложение, но я не понимаю, что я выиграю от этого по сравнению с солью для каждого пользователя.Если бы кто-то хотел провести атаку методом грубой силы, он бы знал эту «app_wide_string» и использовал ее при проведении атаки по словарю, верно?

Есть ли веская причина использовать bcrypt вместо моего собственного, как описано выше? Может быть, достаточно того, что я задаю эти вопросы?

Кстати, я только что замерил время существующей функции хеширования, которая у меня есть, и на моем ноутбуке, и я могу генерировать около 7000 хэшей в секунду. Не совсем те одну или две секунды, которые часто предлагают.

Некоторые связанные ссылки:

использование sha256 для хеширования и добавления солей к идентификатору пользователя

SHA512 по сравнению с Blowfish и Bcrypt

Какова оптимальная длина соли для пароля пользователя?

13
задан Community 23 May 2017 в 12:16
поделиться