Подтвердить что ты не робот

Нужна ли мне "случайная соль" один раз за пароль или только один раз на базу данных?

В дополнение к моему предыдущему вопросу о соленых паролях в PHP/MySQL, у меня есть другой вопрос относительно солей.

Когда кто-то говорит "использовать случайную соль" для предварительного/добавления пароля, означает ли это:

  • Создание статической 1-х случайно созданной строки символов или
  • Создание строки символов, которая изменяется произвольно каждый раз, когда пароль создан?

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

4b9b3361

Ответ 1

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

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

Затем вы сохраняете результат хэширования соли и пароля в базе данных hash(salt + password) вместе с salt для каждого пользователя. Вы можете хранить их в отдельных столбцах или все в одном столбце (разделенные символом, который не используется в хэшах, поэтому ;). Пока вы можете получить оба, все будет хорошо.

Однако, если ваша база данных скомпрометирована, либо из-за того, что кто-то получает локальный доступ, либо через атаки SQL-инъекций, тогда будет доступен как соль, так и конечный хеш, что означает, что атака грубой силы на пароли пользователей будет тривиальной. Чтобы бороться с этим, как предложено The Rook, вы также можете использовать секретный ключ sitewide, хранящийся в файле локально, в качестве другого ввода вашего метода хэширования, чтобы также понадобился злоумышленник чтобы знать это, чтобы установить эффективную атаку. Это означает, что ваша БД должна быть скомпрометирована, и злоумышленнику потребуется доступ к локальным файлам. Поэтому используйте 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 и т.д.). (Ссылка)

Ответ 2

Второй вариант - правильный.

Традиционно соль хранится вместе с хешированным паролем, но не зашифрована (обычно preappended, например, в unix-паролях)

Обновление: метод, используемый в большинстве новых систем Unix, этот.

Ответ 3

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

Ответ 4

Динамическое изменение соли намного безопаснее, чем наличие одной статической соли.

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

Конкатенация соли до конца пароля, а затем хеширование - это нормально, но это легко догадающаяся формула. Лучше всего придумать свой собственный, т.е. Солить соль и пароль, чтобы создать новую строку, а затем хеш, так как md5 (пароль + соль) уязвим для атаки по-прежнему.