Как постоянно поддерживать количество циклов bcrypt, относящихся к оборудованию текущего года?
Я видел рекомендацию, чтобы количество раундов было установлено на ($currentYear - 2000)
для учета закона Мура, так что 2013 будет 13
раунды и, следовательно, 2^13
Всего итераций. Конечно, вы должны принять во внимание ваше собственное оборудование, чтобы убедиться, что это не займет много времени (я видел 1 second
рекомендуется как "безопасный" для проверки паролей / хэшей, и на моем текущем оборудовании это около 13 раундов.
Это звучит разумно для сайта типа социальной сети? Или я бы настроил себя на очень медленную проверку пароля в будущем, используя ($currentYear - 2000)
?
Кроме того, как вы справляетесь с изменением количества раундов с одного года на следующий? Разве изменение количества раундов не изменит хэши, поэтому не позволяет проверять хэши с 2013 по 2014 год, так как проверка будет использовать дополнительный раунд? Придется ли вам пересчитывать каждый хэш каждый год или как он будет работать точно?
3 ответа
Прежде всего, я подвергаю сомнению эту рекомендацию (корректировка стоимости в зависимости от года). Стоимость должна основываться на скорости вашего оборудования, а не на текущей дате. Если вы не модернизируете свой сервер в период с настоящего момента до 2015 года, нет причин увеличивать стоимость. Все, что вы делаете, это замедляете и без того медленный процесс.
С учетом сказанного я также подвергаю сомнению рекомендацию в 1 секунду для большинства случаев использования. Если вы имеете дело с очень конфиденциальной информацией, 1 секунда (или, возможно, дольше) в порядке. Но для среднего сайта я обычно рекомендую от 0,25 до 0,5 секунд. В некоторых случаях вы можете пойти ниже, но я не смог бы без веских оснований.
Теперь к самому вопросу. Когда вы используете crypt()
или же password_hash()
счетчик итераций сохраняется в формате возвращаемого хэша. На самом деле, соль тоже. Таким образом, вся информация, необходимая для вычисления хэша, включена в него!
И если вы не используете ни один из этих API-интерфейсов (или полифил, который я поддерживаю: password-compat), тогда я действительно должен задаться вопросом, почему вы этого не делаете. Не придумывайте свой собственный крипто-пароль. Не используйте библиотеки, которые используют собственные хеши (например, phpass), если у вас нет веских причин (по определенным правительственным причинам или для совместимости с PHP <= 5.2).
Обычно считается, что bcrypt - самый сильный формат хеширования на сегодняшний день. SCrypt сильнее, но с ним есть некоторые проблемы, и он все еще очень новый (и пока недоступен в ядре PHP). Так что просто используйте bcrypt...
password_hash()
У api есть механизм, позволяющий вам делать то, что вы просите: password_needs_rehash()
, По сути, вы передаете хеш и параметры, которые вы используете сегодня, и он говорит вам, если вам нужно перефразировать его:
if (password_verify($password, $hash)) {
if (password_needs_rehash($hash, PASSWORD_BCRYPT, ['cost' => 14])) {
$hash = password_hash($password);
update_password_in_database($hash);
}
$loggedin = true;
}
Прочитайте RFC для password_hash() для получения дополнительной информации об этом (я собрал данные из большого количества источников и включил ссылки в RFC).
Редактировать - следить за комментарием @AnotherParker:
Преступники не прекращают обновлять свои взломанные коробки только потому, что вы не обновили свой сервер. Вам нужно со временем увеличить рабочий параметр, чтобы предотвратить автономные атаки.
Вроде-правда. Ну, правда, но не соответствует тому, о чем я говорил выше.
Параметр стоимости хеш-функции представляет собой компромисс между затратами времени и усилий. Вы компенсируете некоторое время, чтобы добавить дополнительное усилие к каждому хешу. На том же оборудовании, занимая больше времени, вы получите больше работы. Другой способ получить больше работы - получить более быстрое оборудование.
Но рекомендация состоит в том, чтобы протестировать хеш-функцию на вашем текущем оборудовании и сделать ее настолько дорогой, насколько это возможно. Если 0,5 секунды - это максимум, который вы можете себе позволить сегодня, если только вы не модернизируете свое серверное оборудование, как вам поможет увеличение стоимости? Короче говоря, это не так, потому что вы нарушите установленный вами максимальный срок, это важно.
Таким образом, вы не можете увеличить рабочий параметр, не увеличивая при этом возможности сервера, если вы уже не производите слабые хэши.
Кроме того, проверьте этот ответ по теме
Когда вы используете bcrypt, количество раундов является частью сгенерированного хеша:
crypt ( 'Password', '$2a$04$thisshallbemysalt' );
приведет к чему-то вроде
$2a$04$thisshallbemysalt.rAnd0ml0ok1ngch4rsh3re
2a
после первого знака $ стоит алгоритм bcrypt, а следующий 04
обозначает количество раундов - так что, взглянув на хеш, вы можете увидеть, сколько раундов было сделано для его создания.
Поэтому, когда вы решите, что пришло время увеличить количество раундов, вы можете проверить количество раундов, использованных при генерации сохраненного хеша, когда пользователь входит в систему - и если это не ваше текущее количество раундов, вы повторно хешируете там его пароль и затем и сохраните его как новый хеш (после проверки, конечно, соответствует ли их пароль существующему хешу;-))
Идея растягивания ключа состоит в том, чтобы сделать перебор невозможным, потому что вычисление хэша сотни или тысячи раз отнимает для каждого раунда одинаковое количество дополнительного времени в системе злоумышленников.
Это не очень важно, если это займет 1 секунду или 0,9 секунды или 2,5 секунды. Идея заключается в том, что невозможно перебрать миллионы хэшей паролей в секунду. Это фактор, который имеет значение, а не фактическое количество раундов.
Например, если вы используете хеш SHA256, система может делать х (скажем, 1 000 000) хешей в секунду. Путем растягивания ключа (и, следовательно, хеширования, например, 500 раз) вы уменьшаете эту систему до 1 000 000 / 500 = 2000 попыток в секунду для каждого пароля. Вы эффективно замедляете атакующего в 500 раз. Если вы используете 750 раундов, вы... точно! Замедлите атакующего в 750 раз. Но увеличение количества раундов также влияет на вашу систему / веб-сайт / приложение, поэтому вы не хотите идти слишком высоко "просто чтобы быть уверенным"; пользователи будут жаловаться на медленный вход в систему!
Это связано с тем, что, например, SHA1/256/512, MD4/5 и т. Д. Оптимизированы по скорости. А что вам не нужно, так это оптимизированный по скорости алгоритм, позволяющий замедлить атакующих. Таким образом, раз в несколько лет вы просто увеличиваете количество раундов на некоторый фактор, чтобы время входа в систему для ваших пользователей оставалось приемлемым, но чтобы это замедляло злоумышленника настолько, чтобы не стоило пытаться перебирать хеши (или по крайней мере, чтобы заставить их сосредоточиться на гораздо меньших счетах, а не на всех счетах, например).
Когда вы увеличиваете количество раундов, вы перефразируете, как объясняет CBroe.
Я не знаю, кто придумал рекомендацию 2($ currentYear - 2000) (я бы хотел увидеть источник! Неважно, нашел его), но если вы спросите меня, это полный вздор. Я предлагаю вам прочитать ответы более внимательно, а также проверить этот вопрос / ответ.
Если ваш bcrypt занимает от 0,2 до 0,5 секунд (что является приемлемой "задержкой" при входе в систему, если вы спросите меня об этом), это может означать, что злоумышленник может перебить примерно 5–2 хеша в секунду при одинаковом оборудовании, и если он / возможно, она инвестирует 5 000/2 000 или 5 000 000/2 000 000. По-прежнему невозможно выполнимо перебор всего 160-битного (SHA1), 256-битного (SHA256) или даже 448-битного (bcrypt) пространства за приемлемое время (или даже время жизни).