Соль / хэширование Ruby BCrypt кажется ... неправильным? - PullRequest
1 голос
/ 21 июня 2019

Я создавал соленые пароли в приложении ruby, что я считал стандартным способом:

password_salt = BCrypt::Engine.generate_salt
password_hash = BCrypt::Engine.hash_secret(params[:pword], password_salt)

Но при рассмотрении тестового примера похоже, что соль просто добавляется к хэшированиюпароль:

Fishy looking screencap of user table.

Теперь, как я понимаю, смысл соли, он должен быть соединен с паролем ПЕРЕД хэшированием, чтобы вытолкнуть пароль издиапазон размеров, который может включать в себя любой предварительно вычисленный справочный стол, радужный стол и т. д.Дело в том, что если кто-то получит вашу пользовательскую базу данных, он все равно не сможет взломать пароли, используя таблицу поиска.Если соль добавлена ​​к паролю ПОСЛЕ хеширования, и хакер скачал таблицу пользователей, он ничего не делает для защиты паролей.Хакер может просто удалить соль с фронта, вернуть исходный хеш, а затем запустить радужный стол на хешах, как если бы они никогда не были засолены.

Является ли это такой же неудачей соли, какпо-видимому?Проблема в моем коде?Или это работает как ожидалось и безопасно по причинам, которые мне нужно прочитать?(Ссылка, пожалуйста.)

1 Ответ

4 голосов
/ 21 июня 2019

1) Соль необходима для проверки и, следовательно, должна храниться вместе с хешированным шифротекстом.Будь то два поля в базе данных или одна сбитая строка, не имеет значения.

2) Одна соль = одна радужная таблица.Конечно, злоумышленник может создать новый радужный стол для вашей соли;тем не менее, поскольку время создания радужной таблицы в основном эквивалентно времени для пробования всех паролей, которые должна охватывать радужная таблица, это не слабость, если вы не используете соли повторно.


сценарий использования для радужных таблиц позволяет вычислить его один раз , а затем быстро протестировать несколько паролей.Радужная таблица обычно охватывает все пароли до определенной длины или, по крайней мере, с некоторыми ограничениями (например, с определенным алфавитом или с использованием определенного списка слов).Допустим, у вас есть радужная таблица, которая охватывает все пароли длиной до 8 символов.Поэтому, если у кого-то есть пароль «пароль», радужная таблица будет знать, какой будет ее хешированная форма (например, «WASSPORD» - использование заглавных букв для шифрованного текста и строчных букв для открытого текста для удобства чтения примера), и вы можете посмотреть «WASSPORD» вРадужный столик, и вы видите пароль «пароль» очень быстро.

Однако, скажем, у вас есть соленые «арахис».Пароль становится «peanutspassword», и если вы затем зашифруете его, скажем, вы получите «WASSUPMYCRACKER».Руби напечатал бы "арахис WASSUPMYCRACKER" как соленый хеш.Во время проверки вы разделяете "peanutsWASSUPMYCRACKER" на "peanuts" (соль) и "WASSUPMYCRACKER" (хэш);добавьте «арахис» к введенному пользователем «паролю», чтобы сформировать «peanutspassword», и снова зашифруйте его - вы получите «WASSUPMYCRACKER», что соответствует, и пользователь вошел в систему. Однако, обратите внимание, что «peanutspassword» длиннеечем 8 символов, и не будет в радужной таблице длиной до 8 символов.

Теперь вы можете создать радужную таблицу «арахис», взяв тот же словарь, что и исходная радужная таблица, добавив«арахис» и шифрование, но обычно это занимает больше времени, чем просто перебор пароля («арахис» + «а»? «арахис» + «аардварк»? ...), потому что, по крайней мере, когда вы брут-Force, вы остановитесь, когда найдете правильный пароль.

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

tl; dr: Соль может быть общедоступной;его просто нельзя использовать повторно.


РЕДАКТИРОВАТЬ: Похоже, у вас сложилось впечатление, что Руби просто вставляет соль в хэш несоленого открытого текста.Если бы он это сделал, то можно было бы ожидать, что для того же открытого текста задний конец результата (зашифрованный текст) будет одинаковым, независимо от соли.Легко видеть, что это не так:

3.times { puts BCrypt::Engine.hash_secret("password", BCrypt::Engine.generate_salt) }
# $2a$10$jxUToaac5UUzVRH9SnllKe52W1JMLu5tm0LwyrZ4x4e75O1FCn9Ea
# $2a$10$oBs3TyhgR/r12.cz2kdzh.O9WHVZifDPqTEg0.hGOMn7Befv.8hSy
# $2a$10$8rfQA5nzCZ74DwNrmhAhdOmoQOVhJnBfh0ikiOB0W7ZptwsLPGUwi

По мере изменения соли меняется и шифротекст , также .Таким образом, вы не можете «просто удалить соль с фронта, вернуть исходный хеш обратно, а затем запустить радужный стол на хешах, как будто они никогда не были засолены».

...