Параметры PBKDF2: соль, число итераций, хеш, длина ключа

PBKDF2 в Web Crypto API используется для получения криптографических ключей из паролей. В основе лежит функция многократного хеширования, которая превращает слабый пользовательский пароль в устойчивый ключ. Без правильной настройки параметров результат остаётся уязвимым к перебору и словарным атакам.

Соль — случайный набор байтов, который добавляется к паролю перед началом вычислений. Её основная задача — исключить возможность использования заранее подготовленных таблиц (rainbow tables) и обеспечить уникальность результата даже при одинаковых паролях.

В Web Crypto API соль передаётся как ArrayBuffer или Uint8Array.

Ключевые свойства соли:

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

Пример генерации соли:

const salt = crypto.getRandomValues(new Uint8Array(16));

Соль сохраняется вместе с результатом деривации ключа, поскольку без неё невозможно восстановить тот же ключ из пароля.


Число итераций (iterations)

Итерации определяют, сколько раз хеш-функция будет применена к данным. Это основной параметр, влияющий на стойкость PBKDF2 против атак перебора.

Чем выше число итераций, тем:

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

В Web Crypto API параметр задаётся числом:

iterations: 100000

Практические значения:

  • 10 000 — устаревшее минимальное значение (не рекомендуется)
  • 100 000 — базовый уровень для современных приложений
  • 310 000+ — более безопасный вариант для новых систем
  • миллионы — применяются в высокозащищённых системах, но влияют на производительность

Баланс производительности:

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


Хеш-функция (hash)

PBKDF2 опирается на криптографическую хеш-функцию, которая используется на каждом шаге итераций. В Web Crypto API выбор осуществляется через алгоритмы SHA.

Поддерживаемые значения:

  • "SHA-1" (устаревший, не рекомендуется)
  • "SHA-256" (минимальный современный стандарт)
  • "SHA-384" (повышенная стойкость)
  • "SHA-512" (максимальная стойкость среди стандартных вариантов)

Пример выбора:

hash: "SHA-256"

Влияние выбора хеша:

  • SHA-1 уже считается криптографически слабым
  • SHA-256 является стандартом де-факто
  • SHA-512 обеспечивает более высокую стойкость, но требует больше ресурсов

Хеш-функция влияет на внутреннюю стойкость PBKDF2, поскольку каждый цикл итерации использует её как базовую операцию.


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

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

Задаётся в байтах:

derivedKeyLength: 32

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

  • 16 байт (128 бит) — минимально допустимый уровень
  • 32 байта (256 бит) — стандарт для AES-256
  • 64 байта (512 бит) — используется в более сложных схемах

Важные особенности:

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

Полная структура параметров PBKDF2 в Web Crypto API

PBKDF2 в Web Crypto API используется через crypto.subtle.deriveKey или crypto.subtle.deriveBits.

Конфигурация выглядит следующим образом:

const algorithm = {
  name: "PBKDF2",
  salt: salt,
  iterations: 100000,
  hash: "SHA-256"
};

Пример получения ключа AES:

const baseKey = await crypto.subtle.importKey(
  "raw",
  new TextEncoder().encode("password123"),
  "PBKDF2",
  false,
  ["deriveKey"]
);

const derivedKey = await crypto.subtle.deriveKey(
  algorithm,
  baseKey,
  {
    name: "AES-GCM",
    length: 256
  },
  false,
  ["encrypt", "decrypt"]
);

deriveBits vs deriveKey

PBKDF2 может использоваться в двух режимах:

deriveBits

Возвращает “сырые” байты ключа:

const bits = await crypto.subtle.deriveBits(
  algorithm,
  baseKey,
  256
);

Используется когда нужно:

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

deriveKey

Сразу возвращает объект CryptoKey:

const key = await crypto.subtle.deriveKey(
  algorithm,
  baseKey,
  { name: "AES-GCM", length: 256 },
  false,
  ["encrypt", "decrypt"]
);

Используется когда:

  • требуется готовый ключ для Web Crypto операций
  • важна типизация и защита ключа внутри браузера

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

Все параметры PBKDF2 работают совместно:

  • salt определяет уникальность результата
  • iterations определяет вычислительную сложность
  • hash задаёт криптографическую основу процесса
  • derivedKeyLength определяет размер результата

Изменение одного параметра полностью меняет итоговый ключ.


Криптографические требования к параметрам

Соль

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

Итерации

  • не менее 100 000 для современных систем
  • увеличиваются с ростом вычислительной мощности оборудования

Хеш

  • SHA-256 как базовый минимум
  • SHA-512 для усиленной защиты

Длина ключа

  • соответствует требованиям алгоритма шифрования (AES-128/256 и т.д.)

Ошибки конфигурации

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

Слабая соль

Если соль фиксирована или короткая:

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

Малое число итераций

  • ускоряет brute-force атаки
  • делает защиту формальной

Использование SHA-1

  • снижает криптографическую стойкость
  • создаёт потенциальные коллизии

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

PBKDF2 не предназначен для защиты от современных высокопроизводительных атак сам по себе, но при корректной настройке остаётся применимым:

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

Практическая структура хранения

При использовании PBKDF2 обычно сохраняются:

  • salt (в открытом виде)
  • iterations
  • hash algorithm identifier
  • derived key (или зашифрованные данные, защищённые ключом)

Пример структуры:

{
  "salt": "base64...",
  "iterations": 150000,
  "hash": "SHA-256",
  "keyLength": 32
}

Совместимость с Web Crypto API

PBKDF2 реализован через SubtleCrypto:

crypto.subtle.importKey(...)
crypto.subtle.deriveKey(...)
crypto.subtle.deriveBits(...)

Поддержка:

  • Chrome
  • Firefox
  • Edge
  • Safari

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

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

Роль параметров в реальных сценариях

PBKDF2 используется в:

  • хранении паролей (через производные ключи)
  • генерации ключей шифрования файлов
  • защите локальных данных
  • совместимости с серверными системами (OpenSSL, Java, .NET)

Во всех случаях корректная настройка параметров определяет устойчивость всей схемы безопасности.