PBKDF2: алгоритм и параметры итераций

Назначение PBKDF2 в контексте SJCL

PBKDF2 (Password-Based Key Derivation Function 2) применяется для преобразования пароля в криптографически стойкий ключ фиксированной длины. В библиотеке Stanford JavaScript Crypto Library (SJCL) этот алгоритм используется как стандартный механизм усиления паролей перед их использованием в шифровании или аутентификации.

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


Формальная модель PBKDF2

PBKDF2 основан на повторяющемся применении HMAC с криптографической хеш-функцией. В SJCL используется HMAC-SHA256 как базовый PRF.

Функция ключа определяется как:

(P, S, c, dkLen) = _1 | 2 | | {dkLen/hLen }

где:

    1. — пароль
    1. — соль (salt)
    1. — число итераций
  • (dkLen) — длина выходного ключа
  • (hLen) — длина вывода хеш-функции
  • (T_i) — блоки производного ключа

Каждый блок (T_i) вычисляется через функцию (F):

T_i = F(P, S, c, i)

Функция (F) определяется как XOR последовательных значений (U_j):

F(P, S, c, i) = U_1 U_2 U_c

где:

  • (U_1 = (P, S | i))
  • (U_j = (P, U_{j-1}))

Роль соли (salt)

Соль в PBKDF2 предотвращает атаки с использованием радужных таблиц и предварительно вычисленных хешей.

Свойства соли:

  • должна быть уникальной для каждого пароля
  • должна быть случайной
  • не обязана быть секретной
  • обычно 128 бит или больше

В SJCL соль передаётся как массив бит или строка и автоматически включается в вычисление HMAC.


Итерации и их влияние на безопасность

Параметр итераций (c) определяет количество повторений PRF.

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

T_{} c

Практические последствия увеличения c:

  • увеличение времени вычисления ключа
  • линейное замедление brute-force атак
  • рост устойчивости к GPU/ASIC атакам

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

  • устаревшие системы: 1 000 – 10 000
  • современные рекомендации: 100 000 – 600 000+
  • высокозащищённые сценарии: до нескольких миллионов (в зависимости от UX требований)

PBKDF2 в SJCL: реализация и интерфейс

В SJCL функция PBKDF2 доступна через sjcl.misc.pbkdf2.

Сигнатура

sjcl.misc.pbkdf2(password, salt, iterations, keyLength, prf);

Параметры

  • password — строка или массив бит
  • salt — строка или массив бит
  • iterations — число повторений
  • keyLength — длина ключа в битах
  • prf — (опционально) псевдослучайная функция, обычно HMAC-SHA256

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

const sjcl = require("sjcl");

const password = "correct horse battery staple";
const salt = sjcl.random.randomWords(8, 0);

const key = sjcl.misc.pbkdf2(
    password,
    salt,
    200000,
    256
);

В этом примере:

  • соль генерируется криптографически случайно
  • 200 000 итераций обеспечивают баланс между безопасностью и производительностью
  • выходной ключ имеет длину 256 бит

Внутренние этапы вычисления

PBKDF2 проходит несколько фаз:

1. Инициализация PRF

PRF строится на HMAC:

(P, X) = _{}(P, X)


2. Генерация блоков

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


3. Итеративное накопление XOR

Каждая итерация зависит от предыдущей:

  • повышает вычислительную стоимость
  • исключает возможность простого предвычисления

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

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

  • 128 бит — минимально допустимо для старых систем
  • 256 бит — стандарт для современных схем шифрования
  • 512 бит — используется в некоторых HMAC-ориентированных системах

Увеличение длины не влияет на стойкость пароля, но увеличивает стоимость вычислений.


Количество итераций

Главный параметр безопасности PBKDF2.

Увеличение итераций:

  • снижает скорость атак
  • увеличивает задержку логина
  • повышает стоимость серверных операций

Баланс выбирается исходя из допустимой задержки:

  • веб-приложения: ~100–300 мс на операцию
  • локальные приложения: до 1 секунды

Криптографические свойства PBKDF2

PBKDF2 обеспечивает:

  • стойкость к brute-force при достаточном числе итераций
  • устойчивость к rainbow table атакам
  • детерминированность результата
  • независимость от платформы

Ограничения:

  • не защищает от слабых паролей
  • не устойчив к специализированным GPU атакам так же эффективно, как memory-hard функции (Argon2)

Типичные ошибки при использовании SJCL PBKDF2

1. Недостаточное число итераций

Часто используемые значения 1000–10000 сегодня считаются небезопасными.


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

Использование одинаковой соли для разных пользователей приводит к корреляции хешей.


3. Слишком короткий ключ

Снижение длины ключа без необходимости уменьшает криптографическую устойчивость всей системы.


4. Отсутствие адаптации под железо

Фиксированные параметры без учёта производительности серверов приводят либо к уязвимости, либо к деградации UX.


Внутренние особенности SJCL

В реализации SJCL:

  • PBKDF2 построен поверх HMAC-SHA256
  • работа ведётся с 32-битными словами
  • используется оптимизация XOR-накопления
  • поддерживается работа с бинарными и строковыми входами

Это делает библиотеку независимой от платформы и предсказуемой по результатам между браузерами и Node.js.


Практическая модель выбора параметров

При выборе параметров учитываются три переменные:

  • допустимое время вычисления
  • угроза перебора (онлайн/офлайн)
  • аппаратные возможности атакующего

Условно:

  • низкая безопасность: 50k–100k итераций
  • средняя: 200k–500k
  • высокая: 500k+

PBKDF2 остаётся базовым стандартом KDF в JavaScript-экосистеме, а реализация в Stanford JavaScript Crypto Library используется как эталон простоты и переносимости, несмотря на появление более современных memory-hard алгоритмов.