Ruby-BCrypt: указать соль

Можно ли указать, какая соль используется при шифровании строк с помощью ruby-bcrypt?

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

Поэтому я подумал, что зашифрую электронную почту с помощью Bcrypt (перед удалением), а позже я смогу запросить, существует ли этот хеш, когда пользователь захочет снова зарегистрироваться с этим адресом электронной почты?

Но теперь я понял, что bcrypt всегда создает новую соль... Могу ли я как-то указать соль?

Спасибо,

ОТВЕТСТВЕННОСТЬ/ВНИМАНИЕ:

ВООБЩЕ НИКОГДА НЕ СЛЕДУЕТ УКАЗЫВАТЬ СОЛЬ НАПРЯМУЮ - ЭТО НЕБЕЗОПАСНО!!!


person BvuRVKyUVlViVIc7    schedule 24.10.2013    source источник
comment
Разве вы не можете хранить уникальную соль где-нибудь вместе с хэшем пароля? (Если у вас есть только одно поле для работы, вы можете просто вставить туда известный разделитель между хешированным адресом электронной почты и солью)   -  person struthersneil    schedule 25.10.2013
comment
Подождите, я идиот. Bcrypt уже обрабатывает хранение хэша + соли.   -  person struthersneil    schedule 25.10.2013


Ответы (3)


Вы можете использовать BCrypt::Password.create, передав ему электронное письмо, для создания этих хэшей вместе с уникальной солью.

2.0.0-p195 :003 > hashed_email = BCrypt::Password.create '[email protected]'
 => "$2a$10$vX2tl3omW9h4k66XC7/BwOFH0n7EqtH4PJATPa7YVSeJh7TEpt/bK" 
2.0.0-p195 :004 > hashed_email = BCrypt::Password.create '[email protected]'
 => "$2a$10$RdQIHtz.L5To1F1XRK//..h6nHYdQ3uJ2PTgB58e3xufoqgZGqbO6" 
2.0.0-p195 :005 > hashed_email = BCrypt::Password.create '[email protected]'
 => "$2a$10$bTFVXO/d0/sf6SxzCcRMU.zBPcR5yjI6ID6O9J2eXKbqim/jPM3PC" 
2.0.0-p195 :006 > hashed_email = BCrypt::Password.create '[email protected]'
 => "$2a$10$gbXU4UEiHTC0HCnD672Dm.TeBhZeCa6sBiX8Pk50KSXcprDJnEYA." 

Теперь вам не нужно беспокоиться об использовании фиксированной соли, поскольку BCrypt уже сохранил ее вместе с хэшем для вас.

Но, я полагаю, вы определили, что это означает, что позже будут затраты на обработку, связанные со сравнением, хотя вы не можете просто выполнить 'SELECT user WHERE email_hash = hash'.. .

Если вы абсолютно хотите использовать фиксированную соль, вы можете.

salt = BCrypt::Engine.generate_salt
hash = BCrypt::Engine.hash_secret 'hello', salt

(Просто сохраните эту соляную строку где-нибудь, и вы сможете использовать ее позже.)

person struthersneil    schedule 25.10.2013
comment
OP нуждается в фиксированной соли, чтобы поиск электронной почты в БД работал без необходимости хранить открытый текст электронной почты. Я проделал аналогичную работу для номеров кредитных карт, занесенных в черный список, и, насколько мне известно, единственное решение, позволяющее сохранить результат доступным для поиска, - это использовать фиксированную соль. - person Neil Slater; 25.10.2013
comment
Это то, что я описываю после второго абзаца. - person struthersneil; 25.10.2013
comment
Или, по-другому, это означает, что позже будут затраты на обработку, связанные со сравнением, при условии, что сайт достаточно популярен, чтобы проверить тысячу электронных писем, вы говорите минуты Процессорное время, затрачиваемое системой на определение того, была ли регистрация зарегистрирована ранее. При каждой регистрации. - person Neil Slater; 25.10.2013
comment
По ходу я выясняю аргументацию ОП ... а затем тут же даю ответ. Возможно, слова «я бы» слишком многозначительны. Ok. Переформулировано. - person struthersneil; 25.10.2013

Да, ты можешь:

BCrypt::Engine.hash_secret( '[email protected]', "$2a$10$ThisIsTheSalt22CharsX." )

Первые 7 символов технически не являются солью, они идентифицируют алгоритм bcrypt и устанавливают количество итераций равным 2**10 == 1024. Однако для простоты модуль Ruby bcrypt обрабатывает первые символы как часть соли, так что вы надо так же. Вероятно, вам следует использовать

BCrypt::Engine.generate_salt

Чтобы создать свою общую соль, поскольку это не зависит от вас, чтобы придумать что-то «случайное».

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

email = '[email protected]'
full_hash = BCrypt::Engine.hash_secret( email, settings.email_search_salt )
searchable_hash = full_hash[29,31]
# Either store or search . . .
person Neil Slater    schedule 25.10.2013
comment
Ваш ответ правильный, но я приму ответ struthersneil, так как он написал первым... Но спасибо! Я поддержу ваш ответ. - person BvuRVKyUVlViVIc7; 25.10.2013

Это очень старый поток, но все же... вот другие варианты bcrypt с фиксированной солью:

Если безопасность не проблема (просто запутывание): используйте md5

Digest::MD5.hexdigest 'some value'

плюсы: вычислительно недорогой (более быстрая генерация)

минусы: это недорого в вычислительном отношении (более быстрый взлом)

Если безопасность является проблемой, вы можете зашифровать ее с помощью общего секрета (без хэша). См. https://ruby-doc.org/stdlib-2.5.1/libdoc/openssl/rdoc/OpenSSL.html#module-OpenSSL-label-Encryption

person estani    schedule 16.05.2019