Хеширование, соль и хранение хешированных значений

Предположим, вы были вправе решить, как хешированные пароли должны храниться в СУБД. Существуют ли очевидные недостатки в схеме, подобной этой?

Чтобы создать хеш-значение, хранящееся в СУБД, выполните:

  • Значение, уникальное для экземпляра сервера СУБД как часть соли,
  • И имя пользователя как вторая часть соли,
  • И создайте конкатенацию соли с фактическим паролем,
  • И hash всей строки с использованием алгоритма SHA-256,
  • И сохраните результат в СУБД.

Это означало бы, что любой, кто хочет столкнуться с столкновением, должен выполнять работу отдельно для каждого имени пользователя и каждого экземпляра сервера СУБД отдельно. Я планировал бы сохранить фактический хеш-механизм несколько гибким, чтобы позволить использовать новый алгоритм hash-алгоритма NIST ( SHA-3 ), который все еще работает.

Значение, уникальное для экземпляра сервера СУБД, не обязательно должно быть секретным, хотя оно не будет разглашено случайно. objective состоит в том, чтобы убедиться, что если кто-то использует один и тот же пароль в разных экземплярах сервера СУБД, записанные hashи будут разными. Точно так же имя пользователя не будет секретом – просто пароль.

Будет ли преимущество в том, что сначала будет пароль, а также имя пользователя и «уникальное значение» или любая другая перестановка трех источников данных? Или как насчет чередования строк?

Нужно ли добавлять (и записывать) случайное значение соли (за пароль), а также информацию выше? (Преимущество: пользователь может повторно использовать пароль и, возможно, получить другой hash, записанный в базе данных. Недостаток: соль должна быть записана. Я подозреваю, что преимущество значительно перевешивает недостаток.)

Есть довольно много связанных вопросов SO – этот список вряд ли будет всеобъемлющим:

  • Шифрование / Хеширование простых текстовых паролей в базе данных
  • Безопасный hash и соль для паролей PHP
  • Необходимость скрывать соль для хеша
  • Хеш MD5 со стороны клиента со временем
  • Простое шифрование пароля
  • Производство соли и программное обеспечение с открытым исходным кодом
  • Хэши паролей: бинарные поля фиксированной длины или однострочное поле?

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

Соль просто должна быть случайной и уникальной. Он может быть свободно известен, так как он не помогает злоумышленнику. Многие системы будут хранить соль обычного текста в базе данных в столбце рядом с хешированным паролем.

Соль помогает гарантировать, что если два человека (Пользователь А и Пользователь Б) имеют один и тот же пароль, это не очевидно. Без случайной и уникальной соли для каждого пароля значения хеша будут одинаковыми, и, очевидно, если пароль для пользователя A взломан, тогда у пользователя B должен быть одинаковый пароль.

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

Также использование встроенного алгоритма с «рабочим фактором» также означает, что по мере увеличения вычислительной мощности работа, которую должен пройти алгоритм для создания hashа, также может быть увеличена. Например, bcrypt . Это означает, что экономика нападений грубой силы становится несостоятельной. По-видимому, становится намного сложнее создавать таблицы известных hashей, потому что они занимают больше времени для создания; вариации «коэффициента работы» означают, что нужно будет построить больше таблиц.

Я думаю, что вы слишком усложняете проблему.

Начните с проблемы:

  1. Вы пытаетесь защитить слабые пароли?
  2. Вы пытаетесь смягчить атаки радуги?

Механизм, который вы предлагаете, защищает от простой атаки радуги, потому что даже если пользователь A и пользователь B имеют ТАЙНЫЙ пароль, хешированный пароль будет другим. Это, похоже, довольно сложный метод, чтобы солить пароль, который слишком сложный.

  • Что происходит, когда вы переносите БД на другой сервер?
    • Можете ли вы изменить уникальное значение для каждого БД, если это так, тогда можно создать глобальную таблицу радуги, если нет, то вы не сможете восстановить свою БД.

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

Однако он не защитит вас от атаки грубой силы. Поэтому, если вы пытаетесь защитить пользователей, у которых есть дрянные пароли, вам нужно искать в другом месте. Например, если у ваших пользователей есть 4-буквенные пароли, возможно, это будет треск в секундах даже с солью и новейшим алгоритмом хеширования.

Я думаю, вам нужно спросить себя: «Что вы надеетесь получить, сделав это более сложным, чем просто генерирование случайной соли и его сохранение?» Чем сложнее вы делаете свой алгоритм, тем более вероятно, что вы будете непреднамеренно вводить слабость. Это, вероятно, будет звучать snarky, независимо от того, как я это скажу, но это означает, что полезно – что особенного в вашем приложении, что ему нужен новый алгоритм hashирования пароля?

Почему бы не добавить случайную соль к паролю и не использовать эту комбинацию. Затем соедините hash и соль с одним байтом [] и сохраните это в db?

Преимущество случайной соли заключается в том, что пользователь может изменить свое имя пользователя. Соль не должна быть секретной, поскольку она используется для предотвращения атак со словарем.

  • Почему безопасность через неясность - плохая идея?
  • Почему при использовании функции Non-Random IV с режимом CBC существует уязвимость?
  • Должен ли я налагать максимальную длину на пароли?
  • Какая оптимальная длина для паролей пользователей?
  • Хранение данных кредитной карты
  • Давайте будем гением компьютера.