Понятие KDF и необходимость растяжения пароля

KDF (Key Derivation Function) — это функция, преобразующая исходный секрет (чаще всего пароль) в криптографически стойкий ключ фиксированной длины. Основная задача таких функций заключается в том, чтобы сделать использование слабых или предсказуемых паролей устойчивым к перебору и криптоанализу.

В контексте криптографических библиотек на JavaScript, таких как Stanford JavaScript Crypto Library (SJCL), KDF является фундаментальным механизмом для безопасного хранения и использования паролей, генерации ключей шифрования и защиты данных в условиях потенциально небезопасной среды исполнения (браузер, клиентское приложение).


Проблема слабых паролей и ограничений энтропии

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

Ключевая проблема:

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

Без дополнительной обработки пароль напрямую не подходит для криптографических операций.


Атаки на пароли без KDF

При отсутствии функции растяжения пароля (password stretching) возможны следующие типы атак:

Перебор (Brute-force attack)

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

Словарные атаки

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

Радужные таблицы (Rainbow tables)

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


Соль (salt) как базовый механизм защиты

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

Основные свойства соли:

  • делает одинаковые пароли различными в хэшированном виде
  • защищает от радужных таблиц
  • не требует секретности

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


Понятие растяжения пароля (password stretching)

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

Основная идея:

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

Даже если пароль слабый, его проверка становится вычислительно дорогой.


Формальное назначение KDF

KDF выполняет три ключевые задачи:

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

PBKDF2 как основной KDF в SJCL

В Stanford JavaScript Crypto Library используется PBKDF2 (Password-Based Key Derivation Function 2), описанная в RFC 2898.

PBKDF2 основана на применении хэш-функции (в SJCL чаще всего HMAC-SHA256) многократно.

Общая форма PBKDF2

= (P, S, c, dkLen)

где:

  • P — пароль
  • S — соль
  • c — количество итераций
  • dkLen — длина получаемого ключа

Итерации как механизм замедления атак

c

Количество итераций напрямую влияет на устойчивость системы.

Каждая итерация:

  • повторно применяет криптографическую функцию
  • увеличивает время вычисления ключа
  • увеличивает стоимость перебора

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

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

Как SJCL реализует PBKDF2

В SJCL используется реализация PBKDF2 через HMAC-SHA256.

Типичный процесс:

  1. Пароль преобразуется в байтовую последовательность
  2. Генерируется соль (обычно случайная)
  3. Запускается цикл итераций
  4. Вычисляется производный ключ

Функционально это выглядит как:

  • HMAC(password, salt)
  • повторение результата через цепочку вычислений
  • накопление итогового ключа нужной длины

Почему простое хэширование недостаточно

Однократное применение хэш-функции:

  • выполняется слишком быстро
  • легко ускоряется на GPU и ASIC
  • не защищает от массового перебора

PBKDF2 и аналогичные KDF решают эту проблему за счёт:

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

Параметры безопасности KDF

Ключевые параметры, влияющие на стойкость:

Соль

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

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

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

Длина ключа

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

Атака с использованием GPU и значение KDF

Современные атакующие используют параллельные вычисления:

  • GPU ускоряет перебор в сотни и тысячи раз
  • специализированные устройства ещё быстрее

KDF компенсирует это следующим образом:

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

Ограничения PBKDF2 в сравнении с современными KDF

PBKDF2 относится к классу CPU-bound функций. Это означает:

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

Современные альтернативы:

  • scrypt (memory-hard)
  • Argon2 (адаптивная память и время)

SJCL исторически использует PBKDF2 как базовый и широко совместимый вариант.


Практическая роль KDF в архитектуре SJCL

В экосистеме SJCL KDF применяется в нескольких сценариях:

  • генерация ключей для AES-шифрования
  • защита паролей пользователя
  • derivation ключей для HMAC и MAC-операций
  • создание сеансовых ключей

Типовая схема:

Пароль → PBKDF2 → ключ → шифрование данных


Связь KDF и симметричного шифрования

K = (P, S)_K(M)

где:

  • P — пароль
  • S — соль
  • K — производный ключ
  • M — сообщение

Таким образом, KDF является промежуточным слоем между человеческим паролем и криптографическим алгоритмом.


Ошибки использования KDF в реальных системах

Типичные ошибки:

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

Любая из этих ошибок снижает безопасность системы до уровня, пригодного для массового перебора.


Значение растяжения пароля в общей криптографической модели

Растяжение пароля компенсирует фундаментальный дисбаланс:

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

KDF превращает слабый ввод в сильный криптографический материал за счёт вычислительной стоимости, делая атаку экономически невыгодной при корректных параметрах.