Со всеми недавними (например, LinkedIn) обсуждениями паролей я ищу варианты хэширования паролей. После двух чашек кофе и утреннего чтения я больше не криптограф, чем когда начал. И я действительно не хочу притворяться, что я есть.
Конкретные вопросы
-
Используется ли целочисленный уникальный идентификатор пользователя в качестве эффективной соли? (crypt() использует только 16 бит?)
-
Если я просто запускаю sha256() для хэша снова и снова до тех пор, пока не будет использован второй, это приведет к победе над атаками грубой силы?
-
Если я должен задать эти вопросы, должен ли я использовать bcrypt?
Обсуждение/Объяснение:
Цель состоит в том, что если мой пользователь хэширует пароли, они просочились:
- не будет "легко" взломать,
- взломать один пароль не будет выставлять других пользователей, которые используют один и тот же пароль).
То, что я прочитал для # 1, - это то, что хэш-вычисление должно быть дорогостоящим - например, секунду или два, чтобы вычислить и, возможно, потребовать бит или память (чтобы сорвать аппаратное дешифрование).
bcrypt имеет встроенный встроенный скрипт, и, если я правильно понимаю, он более надежный и требует минимального использования памяти.
Но, является ли он столь же эффективным подходом к времени съема, "переигрывая" результат 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 для того, чтобы перевернуть мой собственный, как описано выше? Может быть, тот факт, что я задаю эти вопросы, является достаточной причиной?
BTW - я просто приурочил существующую хеширующую функцию, которую у меня есть и на моем ноутбуке, и я могу генерировать около 7000 хэшей в секунду. Не так часто предлагаются две или две секунды.
Некоторые связанные ссылки:
используя sha256 как хэширование и соление с идентификатором пользователя