Openssl pbkdf2: примеры (PHP)

Функция openssl_pbkdf2 в PHP: примеры и особенности применения
Раздел: Шифрование (OpenSSL)
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

Функция 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 при некорректных типах аргументов.

Расширенные примеры использования

Генерация ключей для шифрования
Пример php
<?
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']);
?>
Использование с различными алгоритмами
Пример php
<?
$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';
    }
}
?>
Совместимость с другими системами
Пример php
<?
// Генерация ключа, совместимого с другой системой
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
JavaScript (Node.js)

В 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'));

PHP openssl_pbkdf2 function comments

En
Openssl pbkdf2 Generates a PKCS5 v2 PBKDF2 string