PBKDF2: параметры, итерации, длина ключа

PBKDF2 (Password-Based Key Derivation Function 2) в CryptoJS используется для преобразования пароля в криптографически стойкий ключ с использованием псевдослучайной функции (обычно HMAC) и множества итераций, что существенно усложняет атаки перебором и радужными таблицами.

Основная идея алгоритма заключается в многократном применении хэш-функции к исходному паролю и соли, что позволяет «растянуть» вычисление ключа во времени и тем самым увеличить стоимость каждой попытки подбора.

В библиотеке CryptoJS функция PBKDF2 вызывается через объект CryptoJS.PBKDF2 и принимает набор параметров, определяющих качество и безопасность получаемого ключа.

Ключевые элементы алгоритма:

  • пароль (password)
  • соль (salt)
  • количество итераций (iterations)
  • длина ключа (key size)
  • псевдослучайная функция (PRF), обычно HMAC-SHA256 или HMAC-SHA1

Пример использования:

const key = CryptoJS.PBKDF2('password', 'salt', {
  keySize: 256 / 32,
  iterations: 10000
});

Пароль и соль

Пароль выступает исходным секретом, который не должен храниться в открытом виде. Соль — это уникальное значение, добавляемое к паролю для предотвращения атак с использованием заранее вычисленных таблиц.

Соль должна быть:

  • уникальной для каждого пользователя
  • достаточно длинной (рекомендуется не менее 16 байт)
  • случайной

Отсутствие уникальной соли делает PBKDF2 уязвимым к массовым атакам на одинаковые пароли.

Итерации: ключевой параметр стойкости

Параметр iterations определяет, сколько раз будет применена хэш-функция к входным данным.

Математически процесс можно описать как повторное применение функции:

T_i = PRF(T_{i-1})

где PRF — псевдослучайная функция, основанная на HMAC.

Каждое увеличение числа итераций линейно увеличивает время вычисления ключа как для легитимного пользователя, так и для атакующего.

Практическое влияние итераций

  • 1000 итераций — устаревший уровень, уязвим к GPU-атакам
  • 10 000 – 100 000 — минимально допустимый диапазон для современных приложений
  • 100 000+ — предпочтительно для систем с высокими требованиями к безопасности

Рост вычислительной сложности можно описать как:

T_{total} = n T_{hash}

где n — число итераций.

Чем выше n, тем дороже становится каждая попытка подбора пароля.

Длина ключа (keySize)

Параметр keySize задаёт длину результирующего ключа в словах по 32 бита. В CryptoJS это важно учитывать, поскольку API работает не с байтами напрямую.

Типичные значения:

  • 128 бит → keySize: 128 / 32 = 4
  • 256 бит → keySize: 256 / 32 = 8

Пример:

const key = CryptoJS.PBKDF2('password', 'salt', {
  keySize: 8,
  iterations: 20000
});

Выбор длины ключа зависит от используемого алгоритма шифрования:

  • AES-128 → 128 бит
  • AES-256 → 256 бит

Недостаточная длина ключа снижает криптостойкость даже при большом числе итераций.

Псевдослучайная функция (PRF)

CryptoJS использует HMAC как базу PRF. Наиболее распространённые варианты:

  • HMAC-SHA1 (по умолчанию в старых конфигурациях)
  • HMAC-SHA256 (рекомендуемый вариант)

Выбор более сильной хэш-функции увеличивает устойчивость к коллизиям и атакам на структуру хэша.

Пример с явным указанием хэша:

const key = CryptoJS.PBKDF2('password', 'salt', {
  keySize: 8,
  iterations: 50000,
  hasher: CryptoJS.algo.SHA256
});

Влияние параметров на безопасность

Все параметры PBKDF2 взаимосвязаны и формируют итоговую стойкость системы.

Сводная зависимость:

  • увеличение iterations повышает время атаки
  • увеличение keySize влияет на стойкость конечного ключа
  • корректная salt устраняет возможность предварительных атак
  • выбор хэш-функции определяет устойчивость PRF

Общая модель вычислительной стоимости атаки может быть выражена как:

C = N iterations

где N — количество проверяемых паролей.

Частые ошибки при использовании PBKDF2 в CryptoJS

Недостаточное количество итераций

Одно из наиболее критичных упрощений — использование значений ниже 10 000, что делает алгоритм уязвимым к перебору на GPU.

Повторное использование соли

Использование одной и той же соли для разных пользователей или ключей приводит к снижению энтропии и упрощает анализ атакующему.

Неправильный keySize

Ошибка заключается в указании длины в байтах вместо слов (32-bit words), что приводит к некорректной длине ключа.

Отсутствие обновления параметров

Криптографические параметры должны пересматриваться по мере роста вычислительных мощностей атакующих систем.

Рекомендованные настройки для CryptoJS

Для современных приложений типовая конфигурация PBKDF2 выглядит следующим образом:

  • iterations: от 100 000 и выше
  • keySize: 256 бит (8 слов)
  • salt: случайные 16–32 байта
  • hasher: SHA-256

Пример конфигурации:

const key = CryptoJS.PBKDF2(password, salt, {
  keySize: 8,
  iterations: 100000,
  hasher: CryptoJS.algo.SHA256
});

Такая конфигурация обеспечивает баланс между производительностью и устойчивостью к атакующим сценариям, включая перебор и атаки с использованием специализированного оборудования.