Создание хэша пароля в 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 секунды.

Другие вопросы по тегам