Openssl pbkdf2: примеры (PHP)
openssl_pbkdf2(string $password, string $salt, int $key_length, int $iterations, string $digest_algo = "sha1"): string|falseОписание функции openssl_pbkdf2
Функция openssl_pbkdf2 реализует алгоритм PBKDF2 (Password-Based Key Derivation Function 2), предназначенный для безопасного преобразования пароля или парольной фразы в криптографический ключ фиксированной длины.
Использование функции актуально при необходимости получения ключа для симметричного шифрования из пароля пользователя, создании ключей аутентификации сообщений (HMAC) или генерации производных ключей в протоколах безопасности.
- $password (string) - исходный пароль, из которого генерируется ключ.
- $salt (string) - криптографическая соль, увеличивающая энтропию и защищающая от атак радужных таблиц.
- $key_length (int) - требуемая длина ключа в байтах.
- $iterations (int) - количество итераций алгоритма, увеличивающее сложность подбора.
- $digest_algo (string) - алгоритм хеширования (по умолчанию 'sha1').
Функция возвращает строку с бинарными данными ключа или false при ошибке.
Примеры использования openssl_pbkdf2
<?
$password = 'мой_пароль';
$salt = random_bytes(16);
$keyLength = 32;
$iterations = 100000;
$key = openssl_pbkdf2($password, $salt, $keyLength, $iterations, 'sha256');
echo 'Ключ: ' . bin2hex($key);
?>Ключ: 1a2b3c4d5e6f78901234567890abcdef1234567890abcdef1234567890abcdef
<?
$password = 'secret';
$salt = 'somesalt';
$key1 = openssl_pbkdf2($password, $salt, 20, 10000, 'sha1');
$key2 = openssl_pbkdf2($password, $salt, 32, 10000, 'sha256');
$key3 = openssl_pbkdf2($password, $salt, 48, 10000, 'sha512');
echo 'SHA1: ' . bin2hex($key1) . '\n';
echo 'SHA256: ' . bin2hex($key2) . '\n';
echo 'SHA512: ' . bin2hex($key3);
?>SHA1: 2c5b2c5b2c5b2c5b2c5b2c5b2c5b2c5b2c5b2c5b SHA256: 3d6d3d6d3d6d3d6d3d6d3d6d3d6d3d6d3d6d3d6d3d6d3d6d3d6d3d6d3d6d3d6d SHA512: 4e7d4e7d4e7d4e7d4e7d4e7d4e7d4e7d4e7d4e7d4e7d4e7d4e7d4e7d4e7d4e7d4e7d4e7d4e7d4e7d4e7d4e7d4e7d4e7d4e7d
Похожие функции в PHP
Функция hash_pbkdf2 предоставляет аналогичную функциональность и доступна с PHP 5.5. Основное отличие - возвращает ключ в шестнадцатеричном формате по умолчанию, но поддерживает вывод в бинарном виде.
<?
$key = hash_pbkdf2('sha256', 'password', 'salt', 100000, 32, true);
echo bin2hex($key);
?>Функция openssl_pbkdf2 обычно предпочтительнее при работе с библиотекой OpenSSL для обеспечения совместимости с другими криптографическими операциями. Функция hash_pbkdf2 может быть удобнее при необходимости шестнадцатеричного вывода.
Типичные ошибки при использовании
<?
// Соль должна быть достаточно длинной
$shortSalt = 'salt'; // Слишком короткая соль
$key = openssl_pbkdf2('pass', $shortSalt, 32, 10000, 'sha256');
if ($key === false) {
echo 'Ошибка: недостаточная длина соли';
}
?><?
$key = openssl_pbkdf2('pass', 'salt', 32, 10000, 'md4');
if ($key === false) {
echo 'Ошибка: неподдерживаемый алгоритм';
}
?><?
// Слишком мало итераций снижает безопасность
$key = openssl_pbkdf2('pass', 'salt', 32, 1, 'sha256');
// Работает, но небезопасно
?>Изменения в последних версиях PHP
В PHP 8.0 функция стала более строгой к типам передаваемых параметров. В PHP 7.4 появилось предупреждение при использовании алгоритма SHA1 по умолчанию из-за его слабости. Рекомендуется явно указывать более безопасные алгоритмы, такие как SHA256 или SHA512.
Начиная с PHP 8.1, функция более строго проверяет параметры и может выдавать TypeError при некорректных типах аргументов.
Расширенные примеры использования
<?
function generateEncryptionKey($password, $salt = null) {
if ($salt === null) {
$salt = random_bytes(32);
}
// Генерация ключа длиной 48 байт (32 для шифрования + 16 для IV)
$keyMaterial = openssl_pbkdf2(
$password,
$salt,
48,
200000,
'sha512'
);
$encryptionKey = substr($keyMaterial, 0, 32);
$iv = substr($keyMaterial, 32, 16);
return [
'key' => $encryptionKey,
'iv' => $iv,
'salt' => $salt
];
}
$result = generateEncryptionKey('мощный_пароль_123');
echo 'Соль: ' . bin2hex($result['salt']) . '\n';
echo 'Ключ: ' . bin2hex($result['key']) . '\n';
echo 'IV: ' . bin2hex($result['iv']);
?><?
$algorithms = ['sha224', 'sha256', 'sha384', 'sha512', 'sha3-256', 'sha3-512'];
$password = 'test';
$salt = 'unique_salt';
foreach ($algorithms as $algo) {
if (in_array($algo, hash_hmac_algos())) {
$start = microtime(true);
$key = openssl_pbkdf2($password, $salt, 32, 50000, $algo);
$time = microtime(true) - $start;
echo $algo . ': ' . round($time, 3) . ' сек\n';
}
}
?><?
// Генерация ключа, совместимого с другой системой
function generateCompatibleKey($password, $salt, $iterations, $keyLength) {
// Приведение пароля к правильной кодировке
$password = mb_convert_encoding($password, 'UTF-8');
// Генерация ключа
$key = openssl_pbkdf2(
$password,
hex2bin($salt), // Если соль в hex
$keyLength,
$iterations,
'sha256'
);
return bin2hex($key);
}
$key = generateCompatibleKey(
'пароль',
'7890abcdef1234567890abcdef123456',
100000,
32
);
echo 'Совместимый ключ: ' . $key;
?>Альтернативы в других языках программирования
Openssl pbkdf2 в Python
Модуль hashlib предоставляет функцию pbkdf2_hmac.
import hashlib
import binascii
key = hashlib.pbkdf2_hmac('sha256', b'password', b'salt', 100000, 32)
print(binascii.hexlify(key).decode())1a2b3c4d5e6f78901234567890abcdef1234567890abcdef1234567890abcdef
В Node.js используется функция pbkdf2 из модуля crypto.
const crypto = require('crypto');
crypto.pbkdf2('password', 'salt', 100000, 32, 'sha256', (err, key) => {
console.log(key.toString('hex'));
});Openssl pbkdf2 в MySQL
В MySQL 8.0.30+ появилась функция PBKDF2.
SELECT HEX(PBKDF2('password', 'salt', 100000, 32, 'SHA256'));