Стоимость операций seal и unseal

Модель вычислительной стоимости

Операции seal и unseal в Iron относятся к классу криптографически тяжёлых преобразований, где основная стоимость определяется не сериализацией данных, а многократными вычислениями в алгоритмах симметричного шифрования и деривации ключей. В отличие от обычных операций преобразования строк или объектов, здесь каждая операция включает набор последовательных этапов, часть из которых имеет экспоненциально более высокую стоимость по сравнению с типичными вычислениями в JavaScript.

Главная особенность заключается в том, что стоимость не является фиксированной: она линейно зависит от параметров конфигурации (например, числа итераций PBKDF2) и размера входных данных.


Что происходит внутри seal

Операция seal представляет собой процесс упаковки произвольного объекта в защищённую строку. Внутренний конвейер включает несколько стадий:

  1. Сериализация входного значения в строку (обычно JSON).
  2. Генерация криптографического ключа из пароля.
  3. Создание случайного salt и IV (initialization vector).
  4. Шифрование данных симметричным алгоритмом.
  5. Формирование HMAC для защиты целостности.
  6. Кодирование результата (base64 или аналогичное представление).

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


Что происходит внутри unseal

Операция unseal выполняет обратное преобразование и включает дополнительные проверки:

  1. Декодирование строки и разбор структуры контейнера.
  2. Повторная генерация ключа из пароля и salt.
  3. Проверка HMAC перед расшифровкой.
  4. Расшифровка данных.
  5. Десериализация результата.

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


Криптографические операции и их сложность

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

  • PBKDF2 (или аналогичный KDF)
  • AES-256 (или другой симметричный алгоритм)
  • HMAC-SHA256

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

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


Ключевая деривация (PBKDF2)

В Iron ключ выводится из пароля с использованием PBKDF2, где параметр iterations определяет количество повторений хэш-функции.

Стоимость можно условно выразить как:

C_{KDF} n_{iterations} C_{hash}

Каждая итерация включает криптографический хэш (обычно SHA-256), что делает процесс CPU-bound. Это означает, что увеличение числа итераций линейно увеличивает время выполнения как seal, так и unseal.


Сравнение затрат seal vs unseal

Несмотря на симметричность операций, unseal обычно оказывается немного дороже или эквивалентен seal по стоимости, поскольку включает дополнительную стадию проверки HMAC до расшифровки.

При типичной конфигурации:

  • seal: KDF + шифрование + HMAC
  • unseal: KDF + HMAC проверка + расшифровка + десериализация

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


Факторы влияния

На реальную стоимость операций влияют следующие параметры:

  • число итераций PBKDF2
  • размер полезной нагрузки (payload)
  • частота вызовов в приложении
  • параллелизм выполнения (event loop Node.js)
  • нагрузка на GC при сериализации JSON

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


Практические оптимизации

Снижение стоимости операций возможно за счёт архитектурных решений:

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

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


Профилирование и узкие места

При анализе производительности в Node.js основной вклад в задержку обычно дают:

  • CPU-время PBKDF2
  • блокировка event loop при синхронных вызовах
  • аллокации строк при сериализации
  • base64-кодирование и декодирование

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

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