Синхронный и асинхронный интерфейс библиотеки

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

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

  • синхронные утилиты общего назначения
  • асинхронный интерфейс SubtleCrypto

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


Синхронные операции: ограниченный, но критически важный набор

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

crypto.getRandomValues

Единственная широко используемая синхронная криптографическая функция:

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

Эта функция:

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

Причины синхронной реализации

Генерация случайных чисел реализована синхронно по следующим причинам:

  • необходимость немедленного доступа к энтропии
  • отсутствие тяжёлых вычислений на уровне API
  • использование системных источников случайности (например, /dev/urandom или аналогов в ОС)
  • критическая зависимость других криптографических операций от случайных значений

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


Асинхронный интерфейс SubtleCrypto

Основная часть Web Crypto API реализована через объект crypto.subtle, который предоставляет набор криптографических примитивов:

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

Все методы SubtleCrypto возвращают Promise, что делает их асинхронными по умолчанию.

Пример:

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

Причины асинхронной модели SubtleCrypto

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

1. Тяжёлые вычисления

Криптографические операции могут включать:

  • модульные возведения в степень (RSA)
  • эллиптические кривые (ECDSA, ECDH)
  • итеративные функции хэширования
  • симметричное шифрование больших массивов данных

Эти операции потенциально блокируют основной поток JavaScript, если выполняются синхронно.


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

В большинстве браузеров Web Crypto API опирается на системные библиотеки:

  • Windows CNG / CryptoAPI
  • OpenSSL (в некоторых реализациях)
  • Secure Enclave / hardware-backed modules

Вызовы к этим системам происходят через асинхронные IPC-механизмы.


3. Изоляция выполнения и безопасность

Асинхронная модель позволяет:

  • предотвращать блокировку UI-потока
  • изолировать криптографические вычисления в отдельных потоках
  • уменьшать риск timing-атак через блокировки исполнения
  • контролировать планирование задач через event loop

Поведение Promises в SubtleCrypto

Каждый метод crypto.subtle возвращает Promise, который разрешается после завершения криптографической операции.

Пример хэширования:

const data = new TextEncoder().encode("message");

const hashBuffer = await crypto.subtle.digest("SHA-256", data);

Особенности:

  • выполнение не блокирует event loop
  • результат возвращается как ArrayBuffer
  • ошибки передаются через Promise rejection

Взаимодействие с event loop

Асинхронные операции Web Crypto API интегрированы в стандартную модель очередей JavaScript.

Последовательность выполнения:

  1. вызов метода crypto.subtle
  2. передача задачи в криптографический слой браузера
  3. выполнение в отдельном потоке или системном провайдере
  4. возврат результата через микрозадачу (microtask)
  5. разрешение Promise

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


Сравнение синхронных и асинхронных частей API

Синхронные операции

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

Асинхронные операции

  • возвращают Promise
  • требуют использования await или .then()
  • выполняются вне основного потока JavaScript
  • охватывают все криптографические алгоритмы

Особенности работы в Web Worker

Асинхронная модель Web Crypto API особенно важна в контексте Web Workers.

В Worker:

  • crypto.subtle работает идентично
  • отсутствует влияние на UI-поток
  • повышается эффективность параллельных вычислений

Пример:

self.onmess age = async (event) => {
  const key = await crypto.subtle.generateKey(
    { name: "AES-GCM", length: 256 },
    true,
    ["encrypt", "decrypt"]
  );

  postMessage(key);
};

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


Форматы передачи данных и асинхронность

Асинхронная природа API тесно связана с использованием ArrayBuffer и структурированных данных.

Причины:

  • бинарные данные могут быть большими
  • копирование данных синхронно было бы дорогостоящим
  • используется механизм transfer (zero-copy) при передаче в Worker

Ошибки и асинхронная обработка

Поскольку все операции SubtleCrypto возвращают Promise, обработка ошибок также асинхронна:

crypto.subtle.decrypt(params, key, data)
  .catch(error => {
    console.error(error);
  });

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

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

Ограничения синхронности в архитектуре Web Crypto

Полностью синхронная криптография в JavaScript невозможна в рамках браузерной модели по нескольким причинам:

  • JavaScript выполняется в одном основном потоке
  • криптографические операции могут быть ресурсоёмкими
  • блокировка UI недопустима по архитектуре браузеров
  • безопасность требует изоляции выполнения

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


Влияние модели на проектирование приложений

Асинхронная архитектура Web Crypto API приводит к необходимости учитывать:

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

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