Соленые хеши паролей
Я пытаюсь создать систему входа в систему для веб-приложения, но я застрял на нескольких моментах. Я храню пароль в своей базе данных, используя хэш sha2-512 со 128-битной случайной солью.
Однако в настоящее время у меня есть пароль, отправленный в виде простого текста в мое приложение с использованием HTML-формы, как при создании учетной записи, так и при входе пользователя в систему. Я знаю, что это неправильно.
Нужно ли хешировать пароль в клиенте? Если да, то как мне учитывать соль, которая в настоящее время генерируется и хранится в базе данных?
ПРИМЕЧАНИЕ: я делаю это, чтобы научиться не использовать в производственной системе
4 ответа
Хэширование пароля на клиенте потребует использования соли на клиенте. Это также предоставляет ваш алгоритм для очень легкого взлома на стороне клиента. Лучше всего выполнить это действие по протоколу SSL (HTTPS), чтобы вся транзакция была зашифрована и аутентификация выполнялась только на сервере.
Т.е.: ваш идентификатор пользователя и пароль передаются в зашифрованном виде от клиента. Веб-сервер расшифровывает данные и передает их в вашу функцию аутентификации на стороне сервера, где вы просматриваете пользователя и связанную соль, выполняете пароль + соль + хеш и сравниваете его с сохраненным хешем для соответствия. Это означает, что хеш, а затем соль вообще не нужно передавать с сервера.
Лучше всего вообще использовать SSL. Если вам нужно было хешировать на стороне клиента, я бы так и сделал:
- Когда вы впервые сохраняете пароль, хешируйте пароль с сохраненной солью, как это обычно делается.
- Когда кому-то нужно войти в систему, отправьте ему сохраненную соль вместе со второй, случайно сгенерированной солью.
- Клиент хеширует незашифрованный пароль с сохраненной солью, затем случайную соль и отправляет хэш на сервер.
- Сервер хеширует сохраненный пароль со случайным числом, использованным в этом запросе, и сравнивает его.
Это безопасно, поскольку гарантирует, что передаваемый хеш уникален для запроса (он использует случайную соль одного запроса), поэтому в будущем невозможно будет подделать имя входа, просто отправив хэш снова. Не опасно отправлять клиенту их сохраненную соль, так как предполагается, что взломщики паролей будут иметь доступ к сохраненной соли (если они получат доступ к БД). Два хэша необходимы для того, чтобы вам никогда не приходилось хранить пароль в виде открытого текста.
Вы должны использовать SSL для передачи зашифрованных паролей, чтобы посредник не мог перехватить пакеты и прочитать то, что отправлено. Даже если вы предварительно хешируете пароль в клиенте, посредник все равно может просто использовать это значение для фальсификации личности.
Что меня действительно беспокоит, так это использование SHA-512. Многие люди используют криптографические хеши для хранения паролей, но популярное мнение упускает очень важный момент: эти хэши были разработаны, чтобы быть быстрыми. То есть одно из требований для того, чтобы стать хешем SHA (или аналогичным), - это возможность быстрого хеширования больших документов на встроенном оборудовании.
Это полная противоположность тому, что вы хотите для хранения паролей, поскольку оно позволяет специализированным подпрограммам на высокопроизводительных графических процессорах грубо форсировать пароли с удивительной и пугающей скоростью!
Вот почему были разработаны специальные хеши для хранения паролей. Я использовал Bcrypt, который достаточно медленный, чтобы не допустить атаки методом грубой силы, настраиваемый для подключения более быстрого оборудования в будущем, и имеет дополнительный бонус для обработки засолки за вас.
Вы действительно должны использовать SSL на любой странице, где вы передаете пароли. Если вы попытаетесь зашифровать их на стороне клиента, это будет в формате javascript и очень легко может быть реверс-инжиниринг.