Создание хэша пароля в PHP 5.5 и настройка стоимости
Я знаю, что PHP 5.5 находится в альфа-версии, но этот класс, который я создаю, просто создается заранее, чтобы использовать функцию хеширования с помощью function_exists().
Я проверил password_hash
документация. Третий аргумент - для параметров $, которые в настоящее время поддерживают два параметра: "соль" и "стоимость".
В нем говорится следующее:
стоимость, которая обозначает алгоритмическую стоимость, которая должна быть использована. Примеры этих значений можно найти на странице crypt().
Когда я захожу на страницу crypt(), документация, которую она дает
Хэширование Blowfish с солью выглядит следующим образом: "$2a$", "$2x$" или "$2y$", двухзначный параметр стоимости "$" и 22 цифры из алфавита "./0-9A-Za-z". Использование символов вне этого диапазона в соли приведет к тому, что crypt() вернет строку нулевой длины. Двузначный параметр стоимости - это логарифм base-2 числа итераций для базового алгоритма хеширования на основе Blowfish, и он должен находиться в диапазоне 04-31, значения вне этого диапазона вызовут сбой crypt(). Версии PHP до 5.3.7 поддерживают только $ 2a $ в качестве префикса соли: PHP 5.3.7 представил новые префиксы для исправления уязвимости безопасности в реализации Blowfish. Пожалуйста, обратитесь к "этому документу для получения полной информации об исправлении безопасности, но в итоге разработчики, ориентирующиеся только на PHP 5.3.7 и более поздние версии, должны использовать" $ 2y $ "вместо"$2a$".
Я не могу обернуть голову вокруг этого. В нем говорится, что PHP 5.3.7 и более поздние версии должны использовать $2y$, но какое значение стоимости я должен использовать, чтобы получить его, и является ли это лучшим значением для выбора? В приведенном ими примере используется значение 7, но в соответствии с вышеизложенным оно может доходить до 31, какая разница, если использовать 4, а не 31?
2 ответа
Функция password_hash()
это просто обертка вокруг функции crypt()
и облегчит его правильное использование. Он заботится о генерации безопасной случайной соли и обеспечивает хорошие значения по умолчанию.
Самый простой способ использовать эту функцию:
$hash = password_hash($password, PASSWORD_DEFAULT);
Это означает, что функция будет хэшировать пароль с помощью BCrypt (алгоритм 2y
), генерирует случайную соль и использует стоимость по умолчанию (на данный момент это 10). Это хорошие значения по умолчанию, в частности, я бы не стал создавать собственную соль, там легко допустить ошибки.
Если вы хотите изменить параметр стоимости, вы можете сделать это так:
$hash = password_hash($password, PASSWORD_BCRYPT, ["cost" => 11]);
Увеличение параметра стоимости на 1 удваивает необходимое время для вычисления значения хеш-функции. Параметр стоимости - это логарифм (основание-2) числа итераций, что означает:
$iterations = 2 ^ $cost;
Редактировать:
Я упустил момент, что вы хотите создать свой собственный класс. Для PHP версии 5.3.7 и выше существует пакет совместимости от того же автора, который сделал password_hash()
функция. Вы можете либо напрямую использовать этот код, либо взглянуть на хорошо продуманную реализацию. Для версий PHP до 5.3.7 нет поддержки crypt
с 2y
, Unicode осведомлен алгоритм BCrypt. Вы можете вместо этого использовать 2a
, которая является лучшей альтернативой для более ранних версий PHP. Я сделал пример с большим количеством комментариев, может быть, вы тоже захотите посмотреть.
PS Выражения "соль" и "фактор стоимости" используются правильно в password_hash()
хотя функция crypt() использует слово salt для всех параметров crypt, это немного вводит в заблуждение.
Отказ от ответственности: это с PHP 5.3.10, но, похоже, не очень отличается от вашего описания.
Стоимость относится к стоимости вычислений. Когда вы увеличиваете стоимость, хэширование пароля занимает больше времени
function blowfish_salt($cost)
{
$chars = './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
$salt = sprintf('$2y$%02d$', $cost);
for ($i = 0; $i < 22; ++$i)
$salt .= $chars[rand(0,63)];
return $salt;
}
$password = 'My perfect password';
$cost = $argv[1];
$salt = blowfish_salt($cost);
$hash = crypt($password, $salt);
Когда я запускаю это на моей (старой) машине как
php mycrypt.php 10
возвращается сразу (~0,2 сек), тогда как при
php mycrypt.php 16
это займет около 5,2 секунды.