Что такое Web Crypto API и зачем он нужен

Web Crypto API (интерфейс SubtleCrypto и объект crypto) — встроенный набор средств браузера для выполнения криптографических операций на стороне клиента без использования сторонних библиотек и без выхода за пределы защищённой среды исполнения.

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

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

Ключевая точка доступа к API:

window.crypto.subtle

Ограничения среды выполнения

Использование Web Crypto API возможно только в защищённом контексте:

  • HTTPS-соединение
  • локальный localhost в режиме разработки

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

Основные принципы архитектуры

Web Crypto API построен вокруг нескольких фундаментальных идей:

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

2. Работа с ключами как с объектами, а не строками Ключи представлены объектами CryptoKey, а не сырыми строками или байтовыми массивами. Это снижает риск утечек и неправильного использования.

3. Разделение операций и управления ключами API строго отделяет:

  • генерацию ключей
  • использование ключей
  • экспорт/импорт ключей

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

Поддерживаемые типы криптографических операций

Web Crypto API покрывает четыре основных класса операций:

Хеширование данных

Хеширование выполняется через метод:

crypto.subtle.digest()

Поддерживаемые алгоритмы:

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

Хеширование используется для:

  • проверки целостности данных
  • хранения паролей (в сочетании с солью и KDF)
  • цифровых отпечатков

Симметричное шифрование

Используется один ключ для шифрования и дешифрования.

Основные алгоритмы:

  • AES-CBC
  • AES-GCM (предпочтительный)
  • AES-CTR

Пример области применения:

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

Асимметричная криптография

Используются пары ключей: публичный и приватный.

Алгоритмы:

  • RSA-OAEP (шифрование)
  • RSA-PSS (подписи)
  • ECDSA (эллиптические кривые, подписи)
  • ECDH (обмен ключами)

Применение:

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

Генерация и производные ключи

Web Crypto API поддерживает:

  • генерацию ключевых пар
  • derivation (получение ключей из паролей)

Ключевые функции:

  • generateKey
  • deriveKey
  • deriveBits

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

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

Работа с ключами

Ключи представлены объектом CryptoKey, который содержит:

  • алгоритм
  • назначение (encrypt, decrypt, sign, verify)
  • возможность экспорта (extractable)
  • состояние использования

Пример создания ключа AES:

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

Экспорт и импорт ключей

Ключи могут быть сериализованы только если явно разрешено (extractable: true).

Форматы:

  • raw
  • pkcs8 (приватные ключи)
  • spki (публичные ключи)
  • jwk (JSON Web Key)

Экспорт:

const exported = await crypto.subtle.exportKey("jwk", key);

Импорт:

const imported = await crypto.subtle.importKey(
  "jwk",
  jwkKey,
  algorithm,
  true,
  ["encrypt"]
);

Шифрование и дешифрование данных

Операции шифрования работают с бинарными данными (ArrayBuffer или TypedArray).

Пример AES-GCM:

const iv = crypto.getRandomValues(new Uint8Array(12));

const encrypted = await crypto.subtle.encrypt(
  {
    name: "AES-GCM",
    iv
  },
  key,
  dataBuffer
);

Дешифрование:

const decrypted = await crypto.subtle.decrypt(
  {
    name: "AES-GCM",
    iv
  },
  key,
  encrypted
);

Цифровые подписи

Подписи используются для подтверждения подлинности данных.

Процесс включает:

  • создание подписи (sign)
  • проверку подписи (verify)

Пример:

const signature = await crypto.subtle.sign(
  "RSASSA-PKCS1-v1_5",
  privateKey,
  data
);

Проверка:

const isValid = await crypto.subtle.verify(
  "RSASSA-PKCS1-v1_5",
  publicKey,
  signature,
  data
);

Безопасность и модель угроз

Web Crypto API разработан с учётом следующих требований:

Изоляция ключей Некоторые ключи невозможно извлечь в сыром виде (extractable: false).

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

Контроль алгоритмов Нельзя реализовать произвольную криптографию — только утверждённые алгоритмы.

Защита от side-channel атак на уровне API Браузер скрывает детали выполнения операций.

Типы данных и бинарная модель

API полностью оперирует бинарными структурами:

  • ArrayBuffer
  • TypedArray (Uint8Array, etc.)
  • DataView

Строки необходимо явно кодировать, обычно через TextEncoder:

const encoder = new TextEncoder();
const data = encoder.encode("text");

Производительность

Web Crypto API значительно быстрее JavaScript-библиотек благодаря:

  • нативной реализации алгоритмов
  • аппаратному ускорению AES и SHA
  • отсутствию интерпретационного слоя

Особенно заметна разница при:

  • массовом хешировании
  • симметричном шифровании больших объёмов данных
  • генерации ключей

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

Несмотря на мощность, присутствуют ограничения:

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

Типичные сценарии применения

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

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