Как постоянно поддерживать количество раундов bcrypt, относящихся к оборудованию текущего года?

Я видел рекомендацию о том, что количество раундов должно быть ($currentYear - 2000) для учета закона Мура, так что 2013 будет 13 раундов и, следовательно, 2^13 итоговых итераций. Конечно, вам нужно учитывать собственное оборудование, чтобы оно не занимало слишком много времени (я видел, что 1 second рекомендуется как "безопасный" для проверки паролей/хэшей, а 13 раундов вокруг этой метки на моем текущем оборудовании).

Это разумно подходит для сайта социальной сети? Или я буду настраивать себя на очень медленную проверку пароля в будущем, используя ($currentYear - 2000)?

Также, как вы справляетесь с изменением количества раундов с одного года на другой? Не изменит ли количество раундов хэширование, поэтому не позволит вам проверять хеши с 2013 года в 2014 году, так как проверка будет использовать дополнительный раунд? Вам нужно будет каждый раз пересчитывать каждый хеш или как он будет работать именно?

Ответ 1

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

С учетом сказанного я также ставил под сомнение рекомендацию 1 секунды для большинства случаев использования. Если вы имеете дело с высокочувствительной информацией, 1 секунда (или, возможно, более длинная) в порядке. Но для среднего веб-сайта я обычно рекомендую от 0,25 до 0,5 секунды. В некоторых случаях вы можете пойти ниже, но я бы не стал без особого оправдания.

Теперь, к самому вопросу. Когда вы используете crypt() или password_hash(), счетчик итераций сохраняется в обратном хэш-формате. На самом деле, соль тоже. Поэтому вся информация, необходимая для вычисления хэша, включена в нее!

И если вы не используете ни один из тех API (или polyfill, которые я поддерживаю: password-compat), тогда Мне действительно нужно задаться вопросом, почему вы этого не сделали. Не придумывайте свой пароль crypto. Не используйте библиотеки, которые используют собственные хэши (например, 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 секунды - это максимум, который вы можете себе позволить сегодня, если вы не обновите аппаратное обеспечение сервера, как увеличится стоимость, которая вам поможет? Короче говоря, это не так, потому что вы нарушите максимальный срок, который вы уже определили, важно.

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

Кроме того, проверьте этот ответ на тему

Ответ 2

Когда вы используете bcrypt, количество раундов является частью генерируемого хэша:

crypt ( 'Password', '$2a$04$thisshallbemysalt' );

приведет к чему-то вроде

$2a$04$thisshallbemysalt.rAnd0ml0ok1ngch4rsh3re

2a после того, как первый знак $обозначает bcrypt algorithem, а следующий 04 обозначает количество раундов - так, посмотрев на хэш, вы можете увидеть, сколько раундов, где было сделано его создание.

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

Ответ 3

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

Не важно, требуется ли 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) (Мне бы хотелось увидеть источник! Nevermind, нашел его), но если вы спросите меня, что это полные быки. Я предлагаю вам прочитать ответы более подробно, а также проверить этот вопрос/ответ.

Если ваш bcrypt занимает от 0,2 до 0,5 секунд (что является приемлемой "задержкой" при входе в систему, если вы спросите меня), это означает, что злоумышленник может перетащить от 5 до 2 хэшей в секунду с учетом того же оборудования и если он/она инвестирует в значительной степени 5000/2000 или 5 000 000/2 000 000, возможно. Это все еще не представляется возможным для грубой работы всего 160 бит (SHA1), 256 бит (SHA256) или даже 448 бит (bcrypt) пространства в приемлемое время (или даже время жизни).