Crypt: примеры (PHP)
crypt(string $string, string $salt): stringФункция crypt в PHP
Функция crypt выполняет одностороннее хеширование строки. Основное применение — безопасное хранение паролей и проверка аутентификации. Она возвращает хешированную строку, сформированную с использованием стандартных алгоритмов Unix.
Функция принимает два аргумента:
- string — исходная строка для хеширования. Обычно это пароль.
- salt — соль, которая определяет алгоритм хеширования и его параметры. Этот аргумент не обязателен. Если соль не указана или опущена, PHP генерирует случайную соль для каждого вызова, что делает невозможным прямое сравнение хешей.
Длина возвращаемой строки зависит от выбранного алгоритма.
Примеры использования функции crypt
При каждом вызове без указания соли генерируется новая случайная соль, и результат будет разным.
echo crypt('myPassword');$1$Tk1b01rK$z6h7L5f1L5b5J1b5N5b5.
Строка соли может указывать алгоритм. Для MD5 используется префикс $1$.
echo crypt('password', '$1$somesalt$');$1$somesalt$qP7h2V8sQ7h2V8sQ7h2V8.
Использование Blowfish с указанием стоимости.
echo crypt('password', '$2a$07$usesomesillystringforsalt$');$2a$07$usesomesillystringfore2uDLvp1Ii2e./U9C8sBjqp8I90dH6hi
Проверка пароля с известным хешем.
$hashed_password = '$1$somesalt$qP7h2V8sQ7h2V8sQ7h2V8.';
if (hash_equals($hashed_password, crypt('password', $hashed_password))) {
echo 'Пароль верный.';
} else {
echo 'Пароль неверный.';
}Пароль верный.
Альтернативные функции в PHP
Функции password_hash и password_verify предоставляют более простой и безопасный интерфейс для хеширования паролей. Они автоматически выбирают подходящий алгоритм (по умолчанию BCRYPT) и управляют солью.
$hash = password_hash('пароль', PASSWORD_DEFAULT);
echo $hash;$2y$10$X5z4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C
Функция hash поддерживает широкий набор алгоритмов (SHA-256, SHA-512 и др.), но не предназначена специально для паролей, так как не включает встроенную защиту от перебора.
echo hash('sha256', 'password');5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8
Аналоги функции crypt в других языках
Модуль crypt в Python предоставляет аналогичный интерфейс для хеширования паролей.
import crypt
hashed = crypt.crypt('password', crypt.mksalt(crypt.METHOD_SHA512))
print(hashed)$6$rounds=656000$saltstring$... (хеш)
В JavaScript нет встроенной функции crypt, но существуют библиотеки, например, bcrypt.js.
const bcrypt = require('bcryptjs');
const salt = bcrypt.genSaltSync(10);
const hash = bcrypt.hashSync('password', salt);
console.log(hash);$2a$10$N9qo8uLOickgx2ZMRZoMye...
MySQL имеет функцию PASSWORD, но она предназначена для внутреннего использования и не рекомендуется для приложений.
SELECT PASSWORD('mypass');*6C8989366EAF75BB670AD8EA7A7FC1176A95CEF4
Распространенные ошибки
При проверке пароля необходимо использовать тот же salt, который был применен при создании хеша. Вызов crypt без второго аргумента для проверки приводит к ошибке.
$stored_hash = crypt('password', '$1$somesalt$');
$input = 'password';
$new_hash = crypt($input); // соль генерируется случайно
var_dump($stored_hash === $new_hash);bool(false)
Хеши crypt имеют фиксированную длину в зависимости от алгоритма. Их усечение приводит к невозможности проверки.
$hash = crypt('password', '$1$salt$');
$trimmed_hash = substr($hash, 0, 10);
$check = crypt('password', $trimmed_hash);
var_dump($hash === $check);bool(false)
Изменения в последних версиях PHP
В PHP 8.0 функция crypt теперь принимает необязательный параметр salt как nullable-аргумент. Это изменение улучшает согласованность с современными стандартами PHP. При передаче null используется поведение по умолчанию с генерацией случайной соли.
echo crypt('password', null);$1$5C7b5C7b$5C7b5C7b5C7b5C7b5C7b5.
Расширенные примеры применения crypt
Пример с алгоритмом SHA-512. Соль задается в формате $6$rounds=5000$saltstring$.
$salt = '$6$rounds=5000$saltstring$';
echo crypt('password', $salt);$6$rounds=5000$saltstring$uZsC... (хеш)
Генерация соли с использованием случайных данных и указанием стоимости.
$cost = 10;
$salt = '$2y$' . str_pad($cost, 2, '0', STR_PAD_LEFT) . '$' . substr(str_replace('+', '.', base64_encode(random_bytes(16))), 0, 22) . '$';
echo crypt('password', $salt);$2y$10$abcdefghijklmnopqrstuu... (хеш)
Для безопасного сравнения используется функция hash_equals, чтобы избежать атак по времени.
$user_input = 'password';
$stored_hash = '$1$somesalt$qP7h2V8sQ7h2V8sQ7h2V8.';
$calculated_hash = crypt($user_input, $stored_hash);
if (hash_equals($stored_hash, $calculated_hash)) {
echo 'Аутентификация успешна.';
}Аутентификация успешна.
Создание соли на основе имени пользователя, но с добавлением случайного компонента для безопасности.
$username = 'user123';
$random = bin2hex(random_bytes(4));
$salt = '$1$' . md5($username . $random) . '$';
echo crypt('password', $salt);$1$d8577ed78$... (хеш)