crypt()
Функция crypt() выполняет одностороннее хеширование string в PHP. Синтаксис, алгоритмы, форматы соли и примеры использования.
Функция PHP crypt() выполняет одностороннее хеширование string. «Одностороннее» означает, что вы можете превратить пароль в хеш, но не можете восстановить исходный пароль из хеша — именно это и нужно для хранения паролей. На этой странице рассмотрены синтаксис, форматы соли, выбирающие алгоритм хеширования, проверка сохранённого хеша, а также причины, по которым в современном коде следует предпочитать password_hash().
Синтаксис
crypt(string $string, string $salt = ""): stringФункция принимает два параметра:
$string— входной текст, который требуется захешировать.$salt— string, определяющая алгоритм хеширования и содержащая случайные байты, благодаря которым одинаковые пароли дают разные хеши. Соль является необязательной, но её отсутствие небезопасно (с PHP 8.0 выводится предупреждение): всегда передавайте явную соль.
Возвращаемое значение — захешированная string. Первые символы результата кодируют соль и алгоритм, поэтому хеш является самодостаточным — его можно хранить как есть, и crypt() впоследствии будет знать, как его воспроизвести.
Простой пример
Здесь мы передаём string и соль в crypt(), и функция возвращает хеш. При соли "ab" вывод представляет собой стандартный DES-хеш:
abJnggxhB/yWIОбратите внимание: первые два символа вывода (ab) — это сама соль. Именно так crypt() запоминает, какой алгоритм и какая соль породили данный хеш.
Форматы соли и алгоритмы
Вид соли указывает crypt(), какой алгоритм использовать. Это наиболее важное, что нужно понять о данной функции:
| Префикс соли | Алгоритм | Примечания |
|---|---|---|
(2 символа, без $) | DES | Устаревший, слабый — учитываются только первые 8 символов пароля. Не использовать. |
$1$ | MD5 | Старый; не применять для новых паролей. |
$5$ | SHA-256 | |
$6$ | SHA-512 | Надёжный; поддерживает стоимостной параметр rounds=. |
$2y$ | Blowfish (bcrypt) | Рекомендуемый алгоритм для crypt(). Формат: $2y$<cost>$<22-char salt>. |
Пример bcrypt с явной стоимостью 10:
<?php
$hash = crypt("password123", '$2y$10$usesomesillystringforsalt$');
echo $hash;
?>Вывод начинается с $2y$10$, фиксируя алгоритм и стоимость, чтобы хеш можно было проверить позже:
$2y$10$usesomesillystringforeSNzFqnuq1h/v0NITsGcb4b3qwzSfNIaПроверка пароля
Чтобы сравнить пароль с сохранённым хешем, захешируйте кандидата, используя сохранённый хеш в качестве соли. crypt() извлечёт алгоритм и соль из этого хеша и автоматически воспроизведёт те же параметры:
Вывод:
Password is valid!Используйте hash_equals() вместо == для сравнения — эта функция работает за постоянное время и предотвращает атаки по времени, которые могут раскрыть информацию о хеше.
Когда применять (и что использовать вместо)
crypt() — низкоуровневый, устаревший инструмент. Его легко использовать неправильно: слишком короткая соль, неверный префикс или устаревший формат DES дают слабые хеши. В новом коде предпочитайте высокоуровневые вспомогательные функции, которые оборачивают crypt() и берут на себя генерацию соли и выбор алгоритма:
<?php
$hash = password_hash("password123", PASSWORD_DEFAULT); // generates a strong bcrypt hash + random salt
if (password_verify("password123", $hash)) {
echo "Password is valid!";
}
?>password_hash() и password_verify() — рекомендуемый способ хранения и проверки паролей в современном PHP. Обращайтесь к crypt() только тогда, когда необходимо взаимодействовать с существующей системой, уже хранящей хеши в формате crypt().
Для простого, не связанного с паролями хеширования (контрольные суммы, ключи кэша, ETag) смотрите функции md5() и sha1() — обратите внимание, что они не подходят для паролей. Для работы с другими строковыми функциями смотрите справочник PHP String functions.