Web Crypto API в браузере построен вокруг строгого разделения синхронных и асинхронных операций. Это разделение является ключевым для понимания поведения криптографических функций в JavaScript, поскольку напрямую влияет на производительность, блокировку потока и способ взаимодействия с низкоуровневыми криптографическими механизмами операционной системы.
Вся криптографическая функциональность в браузере сосредоточена в
объекте crypto, внутри которого выделяются две
принципиально разные части:
SubtleCryptoТакое разделение обусловлено тем, что криптографические операции могут иметь различную стоимость: от мгновенного получения случайных байтов до вычислительно тяжёлых операций, таких как RSA-шифрование или ECDSA-подписи.
Синхронный интерфейс Web Crypto API представлен минимальным набором функций, предназначенных для быстрых и безопасных операций, которые не требуют взаимодействия с внешними источниками или длительных вычислений.
Единственная широко используемая синхронная криптографическая функция:
const array = new Uint8Array(16);
crypto.getRandomValues(array);
Эта функция:
PromiseГенерация случайных чисел реализована синхронно по следующим причинам:
/dev/urandom или аналогов в ОС)Синхронность здесь не является проблемой производительности, так как операция по сути представляет собой чтение буфера из защищённого источника.
Основная часть Web Crypto API реализована через объект
crypto.subtle, который предоставляет набор
криптографических примитивов:
Все методы SubtleCrypto возвращают Promise,
что делает их асинхронными по умолчанию.
Пример:
const key = await crypto.subtle.generateKey(
{
name: "AES-GCM",
length: 256
},
true,
["encrypt", "decrypt"]
);
Асинхронность не является случайным выбором, а обусловлена архитектурой безопасности и производительности браузера.
Криптографические операции могут включать:
Эти операции потенциально блокируют основной поток JavaScript, если выполняются синхронно.
В большинстве браузеров Web Crypto API опирается на системные библиотеки:
Вызовы к этим системам происходят через асинхронные IPC-механизмы.
Асинхронная модель позволяет:
Каждый метод crypto.subtle возвращает
Promise, который разрешается после завершения
криптографической операции.
Пример хэширования:
const data = new TextEncoder().encode("message");
const hashBuffer = await crypto.subtle.digest("SHA-256", data);
Особенности:
ArrayBufferPromise rejectionАсинхронные операции Web Crypto API интегрированы в стандартную модель очередей JavaScript.
Последовательность выполнения:
crypto.subtlemicrotask)PromiseЭто означает, что даже при высокой вычислительной нагрузке основной поток остаётся доступным для обработки UI-событий.
PromisegetRandomValuesPromiseawait или
.then()Асинхронная модель Web Crypto API особенно важна в контексте Web Workers.
В Worker:
crypto.subtle работает идентичноПример:
self.onmess age = async (event) => {
const key = await crypto.subtle.generateKey(
{ name: "AES-GCM", length: 256 },
true,
["encrypt", "decrypt"]
);
postMessage(key);
};
Синхронная функция getRandomValues также доступна и
используется без ограничений.
Асинхронная природа API тесно связана с использованием
ArrayBuffer и структурированных данных.
Причины:
Поскольку все операции SubtleCrypto возвращают
Promise, обработка ошибок также асинхронна:
crypto.subtle.decrypt(params, key, data)
.catch(error => {
console.error(error);
});
Типичные причины ошибок:
Полностью синхронная криптография в JavaScript невозможна в рамках браузерной модели по нескольким причинам:
Поэтому единственная синхронная функция ограничена генерацией случайных чисел, а весь остальной функционал вынесен в асинхронный слой.
Асинхронная архитектура Web Crypto API приводит к необходимости учитывать:
Promise при построении криптографических
операцийСинхронный доступ остаётся ограниченным и используется только там, где задержка выполнения критически недопустима или технически несущественна.