Вопрос по hash, security, passwords, blowfish, php – Как хешировать длинные пароли (> 72 символов) с помощью blowfish

84

На прошлой неделе я прочитал много статей о хешировании паролей, и Blowfish, кажется, (один из) лучший алгоритм хеширования на данный момент - но это 'не тема этого вопроса!

Ограничение в 72 символа

Blowfish учитывает только первые 72 символа введенного пароля:


Выход:

string(119) "Wow. This is a super secret and super, super long password. Let's add some special ch4r4ct3rs a#d everything is fine :)"
string(72) "Wow. This is a super secret and super, super long password. Let's add so"
bool(true)

Как видите, только первые 72 символа имеют значение. Твиттер использует blowfish aka bcrypt для хранения своих паролей (https://shouldichangemypassword.com/twitter-hacked.php) и угадайте, что: измените свой пароль в твиттере на длинный пароль длиной более 72 символов, и вы сможете войти в свою учетную запись, введя только первые 72 символа.

Морская рыба и перец

Есть много разных мнений озабрасывать» пароли. Некоторые люди говорят этоЭто не нужно, потому что вы должны предположить, что секретная перечная нить также известна / опубликована, поэтому она нене увеличивает хэш. У меня есть отдельный сервер базы данных, так чтоВполне возможно, что просочилась только база данных, а не постоянный перец.

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

Так что я думаю, что перебросить пароль, по крайней мере, не плохой выбор.

Предложение

Мое предложение получить хэш Blowfish для пароля длиной более 72 символов (и перца):


Это основано наэтот вопрос:password_verify вернуть .false

Вопрос

Какой безопасный способ? Сначала получить хеш SHA-256 (который возвращает 64 символа) или учитывать только первые 72 символа пароля?

ProsПользователь можетвойдите, введя только первые 72 символаВы можете добавить перец без превышения лимита символовВывод hash_hmac, вероятно, будет иметь большую энтропию, чем сам парольПароль хешируется двумя разными функциямиConsТолько 64 символа используются для создания хэша Blowfish



Изменить 1: Этот вопрос касается только PHP-интеграции blowfish / bcrypt. Поблагодарить's для комментариев!

Также см. Openwall'sФреймворк хеширования паролей PHP (PHPass). Его портативный и защищенный от ряда распространенных атак на пароли пользователей. Парень, который написал фреймворк (SolarDesigner), тот же, кто написалДжон Потрошитель и сидит как судья вКонкурс хэширования паролей, Таким образом, он знает кое-что о атаках на пароли. jww
@Blender: Спасибоs для вашего комментария и вашей работы над ним. Я не могВ php нет разных функций для blowfish и bcrypt, хотя они одинаковы. Но делает лиРазве это не имеет никакого значения для меня в php? Я бы предпочел использовать стандартную функцию PHP. Frederik Kammer
Проблема с Bcrypt, а не с Blowfish. Я могу воспроизвести эту проблему только с помощью Python и Bcrypt. Blender
Bcrypt использует алгоритм Blowfish для хеширования паролей. Поэтому вы можетеt использовать bcrypt отдельно от Blowfish. Phil

Ваш Ответ

3   ответа
127

s начать искать там:

Энтропия на персонажа

Количество битов энтропии на байт:

Шестнадцатеричные персонажиБиты: 4Значения: 16Энтропия в 72 символах: 288 битАлфавитно-цифровойБиты: 6Значения: 62Энтропия в 72 знака: 432 битаОбщие» СимволыБиты: 6,5Значения: 94Энтропия в 72 символах: 468 битПолных байтовБиты: 8Значения: 255Энтропия в 72 символах: 576 бит

То, как мы действуем, зависит от того, каких персонажей мы ожидаем.

Первая проблема

Первая проблема с вашим кодом, это то, что ваш "перец" шаг хеша выводит шестнадцатеричные символы (начиная с четвертого параметраhash_hmac() не установлено).

Поэтому, перебивая свой перец, выэффективно сократить максимальную энтропию, доступную для пароля, в 2 раза (с 576 до 288возможный биты).

Вторая проблема

Тем не мение,sha256 только обеспечивает256 биты энтропии в первую очередь. Так что вы'эффективно сократить возможные 576 бит до 256 бит. Ваш хеш-шаг * немедленно * по определению проигрываетпо крайней мере 50%возможный энтропия в пароле.

Вы можете частично решить эту проблему, переключившись наSHA512, где ты'd только уменьшить доступную энтропию примерно на 12%. Но это'Все еще немаловажная разница. Это 12% уменьшает количество перестановок в1.8e19, Тот'большое число ... И этосфактор это уменьшает это ...

Основная проблема

Основная проблема заключается в том, что существует три типа паролей длиной более 72 символов. Влияние этой системы стилей на них будет очень разным:

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

Высокие энтропийные случайные пароли

Это ваши пользователи, использующие генераторы паролей, которые генерируют то, что составляет большие ключи для паролей. Они случайны (генерируются, а не выбираются человеком) и имеют высокую энтропию на каждого персонажа. Эти типы используют старшие байты (символы> 127) и некоторые управляющие символы.

Для этой группы ваша функция хеширования будетсущественно уменьшить их доступную энтропию в.bcrypt

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

Средняя энтропия случайных паролей

Эта группа использует пароли, содержащие общие символы, но не старшие байты или управляющие символы. Это ваши вводимые пароли.

Для этой группы вы собираетесьнемного разблокировать больше энтропии (не создавать ее, но позволить больше энтропии вписаться в пароль bcrypt). Когда я говорю немного, я имею в виду немного. Безубыточность происходит, когда вы максимально используете 512 бит, которые имеет SHA512. Таким образом, пик составляет 78 символов.

Позвольте мне сказать это снова. Для этого класса паролей вы можете сохранить только дополнительные 6 символов, прежде чем закончится энтропия.

Низкие энтропийные неслучайные пароли

Это группа, которая использует буквенно-цифровые символы, которые, вероятно, не генерируются случайным образом. Что-то вроде цитаты из Библии или чего-то подобного. Эти фразы имеют примерно 2,3 бита энтропии на символ.

Для этой группы вы можете значительно разблокировать больше энтропии (не создавать ее, но позволить больше вписываться в ввод пароля bcrypt) путем хэширования. Безубыточность составляет около 223 символов, прежде чем закончится энтропия.

Позволять'Скажи это снова. Для этого класса паролей предварительное хеширование значительно повышает безопасность.

Вернуться в реальный мир

Эти виды расчетов энтропии неэто не имеет большого значения в реальном мире. Важно только угадать энтропию. Тот'Что напрямую влияет на то, что могут сделать злоумышленники. Тот'Это то, что вы хотите максимизировать.

Пока естьнебольшое исследование, котороеушел в угадывание энтропии, есть некоторые моменты, которые яЯ хотел бы отметить.

Возможности случайного угадывания 72 правильных символов подрядочень низкий. Вы'вероятность выиграть в лотерею Powerball 21 раз, чем столкновение ...s как большое число мымы говорим о

Но мы не можем наткнуться на это статистически. В случае фраз вероятность того, что первые 72 символа будут одинаковыми, намного выше, чем для случайного пароля. Но это'по-прежнему тривиально низко (выболее вероятно выиграть в лотерею Powerball 5 раз, из расчета 2,3 бита на персонажа).

Практически

Практически это неэто действительно важно. Вероятность того, что кто-то угадал первые 72 символа правильно, где последние имеют существенное значение, настолько мала, что это 'не стоит беспокоиться. Зачем?

Ну, давайте'Скажи, что тыповторяю фразу Если человек может правильно понять первые 72 символа, они либодействительно повезло (маловероятно) илиобычная фраза Если оно'Общая фраза, единственная переменная - как долго это делать.

Позволять'Взять пример. Позволять'взять цитату из Библии (только потому, что этоs общий источник длинного текста, не по какой-либо другой причине):

Не желай ближнего твоегодом Не желай ближнего твоегожена, или его слуга или служанка, его вол или осел, или все, что принадлежит вашему соседу.

Тот'с 180 символов. 73-й персонажg во-вторыхneighbor's, Если вы так много догадались, выскорее всего, не останавливаясь наnei, но продолжая с остальной частью стиха (так какs, как пароль, вероятно, будет использоваться). Поэтому твояхэш» А не было»много добавить

Кстати: я абсолютно не защищаю использование цитаты из Библии. На самом деле, с точностью до наоборот.

Заключение

Вы'на самом деле не очень поможет людям, которые используют длинные пароли путём хеширования в первую очередь. Некоторым группам вы определенно можете помочь. Некоторых вы можете определенно обидеть.

Но, в конце концов, ничего из этого не является слишком значительным. Числа, с которыми мы имеем дело, простоПУТЬ слишком высоко. Разница в энтропии нетбудет много.

Вы'лучше оставить bcrypt как есть. Вы'с большей вероятностью испортить хеширование (буквальноты уже сделал это, а тыне первый или последний, кто совершит эту ошибку), чем атака,Попытка предотвратить это произойдет.

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

Тот's мои $ 0,02 как минимум (или, возможно, намного больше, чем $ 0,02) ...

Что касается использования "Секрет» Перец:

Буквально нет исследований по добавлению одной хэш-функции в bcrypt. Поэтому этов лучшем случае неясно, если кормитьприправлены» хеш в bcrypt когда-либо вызовет неизвестные уязвимости (мы знаем, что делатьhash1(hash2($value)) может выявить значительные уязвимости вокруг сопротивления столкновению и атаки прообразом).

Учитывая, что тыВы уже рассматриваете вопрос о сохранении секретного ключаперец"), почему бы не использовать его таким образом, чтобыхорошо изучены и поняты? Почему бы не зашифровать хеш до его хранения?

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

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

Примечание: если вы решите это сделать, используйте библиотеку. Для PHP ясильно рекомендую Zend Framework 2'sZend\Crypt пакет. Это'на самом деле единственный, кого ярекомендую в данный момент времени. Это'Мы были тщательно рассмотрены, и он принимает все решения за вас (что очень хорошо) ...

Что-то вроде:

use Zend\Crypt\BlockCipher;

public function createHash($password) {
    $hash = password_hash($password, PASSWORD_BCRYPT, ["cost"=>$this->cost]);

    $blockCipher = BlockCipher::factory('mcrypt', array('algo' => 'aes'));
    $blockCipher->setKey($this->key);
    return $blockCipher->encrypt($hash);
}

public function verifyHash($password, $hash) {
    $blockCipher = BlockCipher::factory('mcrypt', array('algo' => 'aes'));
    $blockCipher->setKey($this->key);
    $hash = $blockCipher->decrypt($hash);

    return password_verify($password, $hash);
}

И это'это полезно, потому что выиспользовать все алгоритмы способами, которые хорошо поняты и хорошо изучены (по крайней мере, относительно). Помните:

Любой, от самого невежественного любителя до лучшего криптографа, может создать алгоритм, который он сам может 'т перерыв.

Брюс Шнайер
Большое спасибо за этот подробный ответ. Это действительно помогает мне! Frederik Kammer
@martinstoeckli: Моя проблема с концепциейперец не в ценности этого. Это'в том, что применение "перец" выходит на неизведанную территорию в терминах криптографических алгоритмов. Тот'не очень хорошая вещь. Вместо этого я считаю, что криптографические примитивы должны быть объединены таким образом, чтобы они были разработаны, чтобы идти вместе. По сути, основная концепция перца звучит для меня в ушах, как говорили некоторые люди, которые ничего не знали о криптографии.Чем больше хэшей, тем лучше! У нас есть соль, перец тоже хорош!, Я'Я бы предпочел иметь более простой, более проверенный и более понятный ircmaxell
@ircmaxell - самый слабый класс паролей не самый редкий. Чтобы определить, будет ли пароль взломан при реальной атаке по словарю, измеритель прочности потребует словарь самостоятельно. Утечка базы данных представляет собой реальную угрозу (инъекция SQL, выброшенные резервные копии, удаленные серверы ...), поэтому добавление секрета на стороне сервера не является академическим шагом, оно помогает, даже если ключ хранится где-то в жестком коде. Ваше решение с шифрованием хэш-значения будет иметь еще одно преимущество: оно позволяет при необходимости обмениваться ключом, мне нравится эта идея. martinstoeckli
@martinstoeckli: Я не согласен там. Хранение секретов - это не тривиальная вещь. Вместо этого, если вы используете bcrypt с хорошей стоимостью (сегодня 12), все, кроме самого слабого класса паролей, безопасны (словарь, а тривиальные пароли - слабые). Поэтому я бы рекомендовал людям сосредоточиться на обучении пользователейизмерители силы и заставить их использовать лучшие пароли в первую очередь ... ircmaxell
2

основанный на дорогостоящем алгоритме настройки ключа Blowfish.

Рекомендуемый предел пароля в 56 байтов (включая нулевой байт завершения) для bcrypt относится к пределу в 448 битов ключа Blowfish. Любые байты за пределами этого предела не полностью смешиваются в результирующий хеш. Поэтому 72-байтовый абсолютный предел для паролей bcrypt не так важен, если учесть фактическое влияние этих байтов на результирующий хэш.

Если вы думаете, что ваши пользователи обычно выбирают пароли длиной более 55 байт, помните, что вы всегда можете вместо этого увеличить количество циклов растяжения пароля, чтобы повысить безопасность в случае нарушения таблицы паролей (хотя это должно быть много по сравнению с добавлением дополнительных персонажи). Если права доступа пользователей настолько критичны, что пользователям обычно требуется очень длинный пароль, то срок действия пароля также должен быть коротким, например, 2 недели. Это означает, что с гораздо меньшей вероятностью пароль останется действительным, в то время как хакер инвестирует свои ресурсы в уничтожение рабочего фактора, участвующего в тестировании каждого пробного пароля, чтобы увидеть, будет ли он создавать соответствующий хеш.

Конечно, в случае, если таблица паролей не была взломана, нам следует разрешить хакерам не более десяти попыток угадать пользователя.s 55-байтовый пароль перед блокировкой пользователяС аккаунта нет;)

Если вы решили предварительно хешировать пароль длиной более 55 байт, вам следует использовать SHA-384, так как он имеет наибольший результат без превышения лимита ».

@zaph Спасибо. Тот'Очень полезная информация. Phil
Дело в том, что чем чаще от пользователя требуется сменить пароль, тем хуже становится выбор пароля, что снижает безопасность. У пользователя есть ограниченное количество хороших запоминаемых паролей, и они заканчиваются, либо выбирая действительно плохие пароли, либо записывая их в заметки, прикрепленные к нижней части клавиатуры, и т. Д. zaph
срок действия пароля также должен быть коротким, например, 2 недели из "очень длинный парольДействительно, зачем тогда даже сохранять пароль, просто используйте сброс пароля каждый раз. Серьезно, это неправильное решение, перейдите к двухфакторной аутентификации с помощью токена. zaph
[ПРОЕКТ NIST Специальная публикация 800-63B Руководство по цифровой аутентификации] (pages.nist.gov/800-63-3/sp800-63b.html), 5.1.1.2. Запомненные секретные верификаторы:Верификаторы НЕ ДОЛЖНЫ требовать произвольного изменения запомненных секретов (например, периодически), Также смНа пути к улучшению требований к паролю Джим Фентон. zaph
Спасибо @zaph. Вы можете указать мне на пример этого? Звучит интересно. Phil
5

Сначала мы должны ответить на вопрос, когда именно перец помогает. Перец защищает только пароли, пока они остаются секретными, поэтому, если злоумышленник имеет доступ к самому серверу, он бесполезен. Гораздо проще атаковать, хотя SQL-инъекция, которая обеспечивает доступ для чтения к базе данных (нашим хэш-значениям), я подготовилдемо SQL-инъекции чтобы показать, насколько это легко (нажмите на следующую стрелку, чтобы получить подготовленный ввод).

Тогда что на самом деле помогает перец? Пока перец остается в секрете, он защищает слабые пароли от атаки по словарю. Пароль1234 станет чем-то вроде1234-p*deDIUZeRweretWy+.O, Этот пароль не только намного длиннее, он также содержит специальные символы и никогда не будет частью какого-либо словаря.

Теперь мы можем оценить, какие пароли будут использовать наши пользователи, вероятно, больше пользователей будут вводить слабые пароли, так как есть пользователи с паролями от 64 до 72 символов (на самом деле это будет очень редко).

Еще одним моментом является диапазон для грубой силы. Хеш-функция sha256 вернет 256-битный выход или комбинацию 1.2E77, что 'слишком много для грубого принуждения, даже для GPUs (если я рассчитал правильно, это потребует около2Е61 года на GPU в 2013 году). Таким образом, мы не получаем реального недостатка в применении перца. Поскольку хэш-значения не являются систематическими, вы не можете ускорить грубое принуждение с помощью общих шаблонов.

Постскриптум Насколько я знаю, ограничение в 72 символа является специфическим для алгоритма самого BCrypt. Лучший ответ, который я нашел, этоэтот.

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

@Panique - проблема не в вычислении хеша BCrypt, этос HMAC раньше. Для генерации хэша SHA OP использует пароль полной длины и использует результат в качестве входных данных для BCrypt. Для проверки он усекает пароль перед вычислением хэша SHA, а затем использует этот совершенно другой результат в качестве ввода для BCrypt. HMAC принимает ввод любой длины. martinstoeckli
Что касается вашего P.P.S, я могу просто сказать: Да, он может проверить усеченный пароль с помощью хеша не усеченного и все еще получитьtrue, Тот'О чем этот вопрос? Посмотрите сами:viper-7.com/RLKFnB Sliq

Похожие вопросы