Почему BCrypt.net GenerateSalt (31) сразу возвращается? - PullRequest
22 голосов
/ 08 февраля 2010

Я наткнулся на BCrypt.net после прочтения Поста Джеффа Этвуда о хранении паролей , который привел меня к рекомендации Томаса Птачека использовать BCrypt для хранения паролей. Что в конечном итоге привело меня к этой C # реализации BCrypt

В комментариях к последней ссылке выше кто-то спросил: «Почему GenerateSalt (30) работает вечно, а GenerateSalt (31), похоже, совсем не требует времени?»

Я запустил BCrypt.HashPassword (пароль, BCrypt.GenerateSalt (31)) и получил свой результат за 0 миллисекунд.

Я выполняю BCrypt.HashPassword ("пароль", BCrypt.GenerateSalt (30)) уже более 5 минут и до сих пор не получил результата.

Я понимаю, что нам, вероятно, не понадобится случайно сгенерированная соль из 30 символов для создания наших хэшей паролей (или необратимое шифрование в случае BCrypt ) в течение многих лет. EDIT Я должен был прочитать код немного, logRounds не имеет никакого отношения к длине соли. Спасибо Аарона.

Итак, почему GenerateSalt (31) возвращает значение почти мгновенно (тогда как это должно занять примерно вдвое больше времени, чем GenerateSalt (30)?

UPDATE

вот исправление:

private byte[] CryptRaw(byte[] password, byte[] salt, int logRounds) {
    // ... snip ...
    uint rounds = 1U << logRounds;
    // ... snip
}

Ответы [ 2 ]

25 голосов
/ 08 февраля 2010

Я подозреваю, что ошибка здесь:

private byte[] CryptRaw(byte[] password, byte[] salt, int logRounds) {
    // ... snip ...
    int rounds = 1 << logRounds;
    // ... snip
}

Когда вы задаете 31 для logRounds, он вычисляется как 2 ^ 32, который не может поместиться в int и переполняется, поэтому хеш фактически выполняется в ... ээ, нулевых проходах. Автор должен был использовать uint вместо этого. Легко исправить!


Также хотел бы прокомментировать это:

Я понимаю, что нам, вероятно, не понадобится случайно сгенерированная соль из 30 символов для создания наших хэшей паролей ...

Обратите внимание, что параметр logRounds не относится к количеству символов / байтов в соли, которое всегда равно 16. Это относится к логарифмической базе числа проходов, которые хеш будет использовать для вычисления; другими словами, это способ масштабирования bcrypt с помощью закона Мура, что делает вычисление функции на несколько порядков дороже, если компьютеры когда-либо становятся достаточно быстрыми для взлома существующих хешей.

10 голосов
/ 08 февраля 2010

Если хеширование с GenerateSalt(31) возвращается почти мгновенно, это ошибка. Вы должны сообщить об этом вверх по течению (у меня есть, для jBCrypt). : -)

По умолчанию количество раундов составляет 10. Это означает, что (если я правильно помню) используется 1024 раунда. Каждый раз, когда вы увеличиваете количество раундов, количество раундов удваивается.

В 30 раундах вы выполняете 1073741824 раундов. Это по праву занимает много времени. При 31 цикле регистрации необходимо выполнить 2147483648 циклов, но я подозреваю, что конкретная реализация, которую вы используете вместо этого, переполняется : - (

...