Серьезная проблема с jBCrypt с checkpw (верните true, если не должно?) - PullRequest
6 голосов
/ 30 мая 2011

РЕДАКТИРОВАТЬ: Хорошо, я нашел какой-то ответ здесь BCrypt говорит, что длинные, похожие пароли эквивалентны - проблема со мной, самоцветом или областью криптографии?

Новый вопрос, однако, как кто-то может порекомендовать использовать bCrypt для хэширования, если вам нужно ограничить длину пароля пользователя в мире, где мы пытаемся научить пользователей выбирать все более сложные пароли, даже пароль, говоря, что ваш пароль должен быть короче чем n символов кажется способом оказаться на пятничных скриншотах thedailywtf.com:)

Оригинальный вопрос ниже:

Я реорганизую старую страницу входа для приложения и решила дать bCrypt повод, используя реализацию JAVA jBCrypt (http://www.mindrot.org/projects/jBCrypt/), и натолкнулась на одну главную пробку шоу.

Проблема в методе checkpw , который всегда возвращает true при использовании очень длинного начального числа. Я собирался посолить пароль пользователя с помощью {InternalSalt} {username} {password}, ​​а затем хэшировать его с помощью bCrypt.

Итак, у меня есть следующий код (как можно более урезанный, чтобы изолировать checkpw).

public class Test {
public static void main(String[] args) {
    String plaintext = "jw~ct/f61y1m7q458GiLVQpiqDK|8kG=d368Id:D@$^_80I{qrn1HM6423{FtestAccountO1nu3jKN";

    String pw_hash = BCrypt.hashpw(plaintext, BCrypt.gensalt());

    if (BCrypt.checkpw("jw~ct/f61y1m7q458GiLVQpiqDK|8kG=d368Id:D@$^_80I{qrn1HM6423{FtestAccountO1nu3jKN", pw_hash))
        System.out.println("It matches");
    else
        System.out.println("It does not match");

}

}

Это, как и должно быть, напечатает "Это соответствует".

Проблема, с которой я столкнулся, заключается в том, что вы, скажем, добавляете, скажем, ааа к паролю, который вы передаете в checkpw, делая его

BCrypt.checkpw ("jw ~ ct / f61y1m7q458GiLVQpiqDK | 8 кг = d368Id: D @ $ ^ _ 80I {qrn1HM6423 {FtestAccountO1nu3jKNaaa", pw_hash)

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

Я что-то пропустил? Я знаю, что не должен быть единственным, кто использует jBcrypt на этом форуме, поскольку я видел BCrypt, рекомендованный во многих постах, когда проводил некоторые исследования.

РЕДАКТИРОВАТЬ: Windows 7 64 бит - Java (TM) SE Runtime Environment (сборка 1.6.0_24-b07)

Ответы [ 2 ]

5 голосов
/ 30 мая 2011

Хорошо, так что формулировка вопроса дала мне достаточно, чтобы понять, что я искал (ура для резинового утенка ).Область криптографии безопасна на данный момент!

XOR реализации BCrypt, использующий P_orig, который составляет целое число 18 4 байта до конца, что ограничивает ваш «ключ» шифрования до 72 байтов.Все, что происходит после 72 байтов, игнорируется (было бы неплохо предупреждение).

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

Источник: BCrypt говорит, что длинные, похожие пароли эквивалентны - проблема со мной, гемом или полемкриптографии?

2 голосов
/ 08 ноября 2014

На самом деле ваш собственный ответ отлично и помог мне найти досадную проблему;) Есть несколько советов для людей, которые добавляют какой-то секрет приложения к простому перед хэшированием (даже еслиони ограничивают длину пароля): включите секрет приложения в end , особенно если секрет приложения имеет длину 72 символа - в противном случае каждое нажатие вернет true!

, поэтому вместо этого:

String hashed = BCrypt.hashpw(APP_SECRET + plain, BCrypt.gensalt())

использование:

String hashed = BCrypt.hashpw(plain + APP_SECRET, BCrypt.gensalt())

Даже если произойдет обрезка Bcrypt, результат checkpw будет действительным!

...