Новая соль должна генерироваться случайным образом для каждого пользователя, и каждый раз, как минимум, он меняет свой пароль.Например, не полагайтесь только на соль для всего сайта, так как это лишает смысла использование соли в первую очередь.
Использование уникальной соли для каждого пользователя означает, что если два пользователя имеют одинаковый парольони не получат такой же результирующий хэш.Это также означает, что атака методом "грубой силы" должна проводиться против каждого пользователя индивидуально, вместо того, чтобы иметь возможность предварительно вычислить радужную таблицу для сайта.
Затем вы сохраняете результат хеширования.соль и пароль в базе данных hash(salt + password)
, а также salt
для каждого пользователя.Вы можете хранить их в отдельных столбцах или все в одном столбце (разделенных символом, который не используется в хешах, например, ;
).Пока вы можете получить оба, все будет в порядке.
Однако, если ваша база данных скомпрометирована, либо из-за того, что кто-то получает локальный доступ, либо с помощью атак с использованием SQL-инъекций, тогда будут доступны как солт, так и финальный хеш, что означает, что атака методом перебора паролей пользователейбыть тривиальнымДля борьбы с этим, как предлагает The Rook , вы также можете использовать секретный ключ, хранящийся в файле локально, в качестве еще одного входа вашего метода хеширования, так что злоумышленнику также необходимо знать это для проведения эффективной атаки.,Это означает, что ваша БД должна быть взломана, а злоумышленнику потребуется доступ к локальным файлам.Таким образом, используя hash(hash(salt + secret) + password)
и т. Д.
Хотя в большинстве алгоритмов вы стремитесь максимально ускорить процесс, для хеширования пароля вы хотите замедлить его, это называется Усиление ключа (или иногда Key Stretching).Если для возврата вашей хэш-функции требуется 0,00001 секунды, кто-то может попытаться перебрать 100 000 паролей в секунду, пока не найдет совпадение.Если вашей хэш-функции требуется 1 секунда, чтобы выдать результат, это не имеет большого значения, если кто-то входит в ваше приложение, но для взлома пароля это более сложная задача, поскольку каждая попытка теперь займет 1 секунду, чтобы получитьрезультат, означающий, что для тестирования каждого перебора парольного пароля потребуется в 100 000 раз больше времени, чем при использовании исходной хэш-функции.
Чтобы замедлить вашу хэш-функцию, вам просто нужно запустить ее несколько раз.Например, вы можете сделать new_hash = salt + password + previous_hash
100 000 раз.Вам может потребоваться отрегулировать количество итераций до более высокого значения, если оно слишком быстрое.Если вы хотите изменить значение позже, сохраните количество итераций с пользовательской записью, чтобы не влиять на ранее сохраненные пароли.
Ваша пользовательская запись должна теперь иметь полечто-то вроде «$<algorithm>$<iterations>$<salt>$<hash>
» (или, если хотите, в виде отдельных полей).
Когда пользователь вводит свой пароль, вы можете получить соль и число итераций из БД, а секрет из всех сторон - излокальный файл и убедитесь, что при выполнении того же числа итераций с солью и паролем полученный хэш соответствует тому, что вы сохранили.
Если пользователь меняет свой пароль, то вы должны сгенерировать новую соль.
Используемый вами метод хеширования не имеет значения (но алгоритм хеширования имеет значение *).Выше я предложил hash(hash(salt + secret) + password)
, но в равной степени это может быть hash(hash(salt) + hash(secret) + hash(password))
.Метод, который вы используете, не меняет эффективность вашего хранилища паролей, один из них на самом деле не более безопасен, чем другой.Полагаясь на то, как вы хэшируете пароль и соль для обеспечения безопасности, это называется безопасность через неизвестность , и ее следует избегать.
* Вы не должны использовать MD5 или SHA-1, так как онисчитаются небезопасными.Вместо этого используйте семейство SHA-2 (SHA256, SHA512 и т. Д.).( Ref )