Как постоянно поддерживать количество раундов 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 (или polyfill что я утверждаю: пароль-compat), тогда я действительно должен задаться вопросом, почему вы этого не делаете. Не изобретайте свой собственный пароль crypto. Не используйте библиотеки, использующие собственные хэши (например, phpass), если у вас нет веских причин (по определенным причинам соответствия требованиям правительства или совместимости с PHP
обычно считается, что 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:
преступники не перестают обновлять свои crackingboxes только потому, что вы не обновили свой сервер. Вам нужно увеличить параметр работы с течением времени, чтобы предотвратить автономные атаки.
сортировка-правда. Да, верно, но упускает смысл того, о чем я говорил выше.
параметр стоимости хэш-функции является компромиссом временных усилий. Вы обмениваете некоторое время, чтобы добавить дополнительные усилия к каждому хэшу. На то же самое оборудование, требующее больше времени, даст больше работы. Другой способ получить больше работы - получить более быстрое оборудование.
но рекомендуется протестировать хэш-функцию на вашем текущем оборудовании и сделать ее настолько дорогой, насколько это возможно. Если 0,5 секунды-это максимум, что вы можете себе позволить сегодня, если вы не обновите серверное оборудование, как увеличение стоимости поможет вам? Короче говоря, это не будет, потому что вы нарушите максимальный срок, который вы уже определили очень важный.
таким образом, вы не можете увеличить рабочий параметр без увеличения возможностей сервера, если вы уже не производили слабые хэши.
кроме того, проверьте этот ответ на эту тему
при использовании bcrypt количество раундов является частью генерируемого хэша:
crypt ( 'Password', 'a$thisshallbemysalt' );
приведет к чему-то вроде
a$thisshallbemysalt.rAnd0ml0ok1ngch4rsh3re
2a
после первого знака $ означает bcrypt algorithem, а затем 04
означает количество раундов - поэтому, глядя на хэш, вы можете увидеть, сколько раундов, где это сделано.
поэтому, когда вы решите, что пришло время увеличить количество раундов, вы можете проверить количество раундов, используемых при создании хранится хэш при входе пользователя в систему и если его не текущее количество раундов, повторно хэш-пароль есть и то, и сохраните его как новый хэш-код (после проверка, соответствует ли их пароль существующему хэшу, конечно ; -))
идея ключ протяженностью сделать грубое принуждение невозможным, потому что вычисление хэша сотни или тысячи раз занимает для каждого раунда столько же дополнительного времени в системе атакующих.
Это не очень важно, если это займет 1 секунду или .9 секунд или 2,5 секунды . Идея заключается в том, что невозможно заставить миллионы хэшей паролей в секунду. Это фактор, который имеет значение, а не фактическое количество раундов.
Если вы используйте, например, хэш SHA256, который система может делать X (скажем, 1,000,000) хэшей в секунду. По ключевым растяжения (и, таким образом, хеширование, например, в 500 раз) вы довести эту систему до 1 000 000 / 500 = 2,000 попыток в секунду для каждого пароля. Вы эффективно замедляете атакующего в 500 раз. Если вы используете 750 вокруг вас... точно! Замедлить атакующего в 750 раз. Но увеличение количества раундов влияет на вашу систему / веб-сайт / приложение, поэтому вы не хотите идти слишком высокий "просто чтобы быть уверенным"; пользователи будут жаловаться на медленные логины!
Это связано с тем, что, например, SHA1/256/512, MD4/5 и т. д. are оптимизирован для скорости. А какой ты не want-это алгоритм, оптимизированный для скорости, чтобы вы могли замедлить атакующих. Таким образом, раз в несколько лет вы просто увеличиваете количество раундов на какой-то фактор, что время входа для ваших пользователей по-прежнему остается приемлемым, но это замедлит злоумышленника достаточно, чтобы не стоило пытаться грубо заставить хэши (или, по крайней мере, заставить их сосредоточиться на гораздо меньшем количестве учетных записей, чем все учетные записи, например).
когда количество раундов вы перепев как CBroe объясняет.
Я не знаю, кто придумал 2($currentYear - 2000) рекомендации (я хотел бы видеть источник! Фигу, нашел), но если вы спросите меня, это полный отстой. Я предлагаю вам читать ответы более внимательно, а также проверить вопрос/ответ.
Если ваш bcrypt принимает .2 для .5 секунд (что является приемлемой "задержкой" при входе в систему, если вы спросите меня), это означало бы, что злоумышленник может грубая сила от 5 до 2 хэшей в секунду с учетом того же оборудования, и если он/она инвестирует тяжело 5,000/2,000 или 5,000,000/2,000,000 возможно. Это все еще не выполнимо для грубой силы всего 160bit (SHA1), 256bit (SHA256) или даже 448bit (bcrypt) пространство в приемлемое время (или даже время жизни).