Web Crypto API (интерфейс SubtleCrypto и объект
crypto) — встроенный набор средств браузера для выполнения
криптографических операций на стороне клиента без использования
сторонних библиотек и без выхода за пределы защищённой среды
исполнения.
Криптография в веб-приложениях долгое время реализовывалась через JavaScript-библиотеки, работающие поверх обычного движка языка. Такой подход имеет фундаментальные ограничения: отсутствие аппаратного ускорения, высокая вероятность ошибок реализации, невозможность строгого контроля над памятью и уязвимость к ряду атак, связанных с интерпретируемым исполнением кода.
Web Crypto API решает эти проблемы за счёт делегирования криптографических операций нативному уровню браузера. Это означает, что операции шифрования, подписи и хеширования выполняются не JavaScript-кодом напрямую, а встроенной реализацией браузера, которая может использовать системные криптографические библиотеки и аппаратные возможности процессора.
Ключевая точка доступа к API:
window.crypto.subtle
Использование Web Crypto API возможно только в защищённом контексте:
localhost в режиме разработкиЭто ограничение связано с тем, что криптографические операции теряют смысл в небезопасной среде, где возможна подмена трафика или внедрение кода.
Web Crypto API построен вокруг нескольких фундаментальных идей:
1. Асинхронность по умолчанию Все операции
возвращают Promise. Это связано с тем, что
криптографические вычисления могут быть ресурсоёмкими и не должны
блокировать основной поток исполнения.
2. Работа с ключами как с объектами, а не строками
Ключи представлены объектами CryptoKey, а не сырыми
строками или байтовыми массивами. Это снижает риск утечек и
неправильного использования.
3. Разделение операций и управления ключами API строго отделяет:
4. Ограниченность доступных алгоритмов Поддерживаются только проверенные и стандартизированные криптографические алгоритмы.
Web Crypto API покрывает четыре основных класса операций:
Хеширование выполняется через метод:
crypto.subtle.digest()
Поддерживаемые алгоритмы:
Хеширование используется для:
Используется один ключ для шифрования и дешифрования.
Основные алгоритмы:
Пример области применения:
Используются пары ключей: публичный и приватный.
Алгоритмы:
Применение:
Web Crypto API поддерживает:
Ключевые функции:
generateKeyderiveKeyderiveBitsЧасто используется PBKDF2:
Ключи представлены объектом CryptoKey, который
содержит:
extractable)Пример создания ключа AES:
const key = await crypto.subtle.generateKey(
{
name: "AES-GCM",
length: 256
},
true,
["encrypt", "decrypt"]
);
Ключи могут быть сериализованы только если явно разрешено
(extractable: true).
Форматы:
rawpkcs8 (приватные ключи)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 полностью оперирует бинарными структурами:
ArrayBufferTypedArray (Uint8Array, etc.)DataViewСтроки необходимо явно кодировать, обычно через
TextEncoder:
const encoder = new TextEncoder();
const data = encoder.encode("text");
Web Crypto API значительно быстрее JavaScript-библиотек благодаря:
Особенно заметна разница при:
Несмотря на мощность, присутствуют ограничения:
Web Crypto API стал базовым стандартом криптографической работы в вебе, заменив небезопасные и медленные пользовательские реализации и предоставив унифицированный, строго контролируемый интерфейс для криптографических операций на стороне клиента.