SubtleCrypto: основной рабочий объект

SubtleCrypto представляет собой основной программный интерфейс для выполнения криптографических операций в Web Crypto API. Доступ к нему осуществляется через свойство crypto.subtle, доступное в глобальном объекте crypto в контексте безопасного происхождения (HTTPS или localhost).

Все операции SubtleCrypto выполняются асинхронно и возвращают Promise, а входные и выходные данные представлены в виде ArrayBuffer или структурированных типов, совместимых с бинарными представлениями данных JavaScript.


Доступ к криптографическому API осуществляется следующим образом:

const subtle = crypto.subtle;

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

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


Общая структура криптографических операций

Все методы SubtleCrypto следуют единому принципу:

  • входные данные преобразуются в бинарный формат (ArrayBuffer)
  • алгоритм описывается объектом параметров
  • результат возвращается через Promise

Типичная схема:

crypto.subtle.method(algorithm, key, data)
  .then(result => {
    // обработка результата
  });

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

SubtleCrypto включает несколько основных групп криптографических функций:

  • хэширование данных
  • симметричное шифрование и расшифрование
  • асимметричное шифрование
  • цифровые подписи и проверка подписи
  • генерация криптографических ключей
  • импорт и экспорт ключей
  • обёртка ключей (key wrapping)

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

Метод digest используется для получения криптографического хэша:

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

crypto.subtle.digest("SHA-256", data).then(hash => {
  console.log(new Uint8Array(hash));
});

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

  • SHA-1 (устаревший и небезопасный)
  • SHA-256
  • SHA-384
  • SHA-512

Результат всегда возвращается как ArrayBuffer.


Генерация ключей: generateKey

Метод generateKey используется для создания симметричных и асимметричных ключей.

Симметричный ключ AES:

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

Асимметричная пара RSA:

crypto.subtle.generateKey(
  {
    name: "RSA-OAEP",
    modulusLength: 2048,
    publicExponent: new Uint8Array([1, 0, 1]),
    hash: "SHA-256"
  },
  true,
  ["encrypt", "decrypt"]
);

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


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

Ключи могут быть сериализованы и восстановлены через importKey и exportKey.

Экспорт ключа:

crypto.subtle.exportKey("jwk", key).then(exported => {
  console.log(exported);
});

Импорт ключа:

crypto.subtle.importKey(
  "jwk",
  jwkKey,
  { name: "AES-GCM" },
  true,
  ["encrypt", "decrypt"]
);

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

  • raw — бинарное представление
  • spki — публичные ключи X.509
  • pkcs8 — приватные ключи
  • jwk — JSON Web Key

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

Наиболее распространённый сценарий — использование AES-GCM.

Шифрование:

const iv = crypto.getRandomValues(new Uint8Array(12));
const encoded = new TextEncoder().encode("secret data");

crypto.subtle.encrypt(
  {
    name: "AES-GCM",
    iv
  },
  key,
  encoded
).then(ciphertext => {
  console.log(new Uint8Array(ciphertext));
});

Расшифрование:

crypto.subtle.decrypt(
  {
    name: "AES-GCM",
    iv
  },
  key,
  ciphertext
).then(result => {
  console.log(new TextDecoder().decode(result));
});

AES-GCM обеспечивает одновременно конфиденциальность и целостность данных.


Цифровые подписи: sign и verify

SubtleCrypto поддерживает цифровые подписи для проверки подлинности данных.

Подписание (ECDSA):

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

crypto.subtle.sign(
  {
    name: "ECDSA",
    hash: "SHA-256"
  },
  privateKey,
  data
);

Проверка подписи:

crypto.subtle.verify(
  {
    name: "ECDSA",
    hash: "SHA-256"
  },
  publicKey,
  signature,
  data
);

Результат проверки — логическое значение.


Обёртка ключей: wrapKey и unwrapKey

Механизм используется для безопасной передачи ключей через другой криптографический ключ.

Обёртка:

crypto.subtle.wrapKey(
  "raw",
  keyToWrap,
  wrappingKey,
  { name: "AES-KW" }
);

Развёртка:

crypto.subtle.unwrapKey(
  "raw",
  wrappedKey,
  wrappingKey,
  { name: "AES-KW" },
  { name: "AES-GCM" },
  true,
  ["encrypt", "decrypt"]
);

Особенности работы с данными

SubtleCrypto не работает со строками напрямую. Любые данные должны быть преобразованы:

const encoder = new TextEncoder();
const decoder = new TextDecoder();

const bytes = encoder.encode("text");
const text = decoder.decode(bytes);

Ключевое ограничение заключается в том, что бинарные данные всегда проходят через ArrayBuffer, что исключает неоднозначность представления.


Безопасные контексты и ограничения

SubtleCrypto доступен только при выполнении условий:

  • HTTPS соединение
  • localhost разрешён как исключение
  • отсутствие ограничений политики безопасности браузера

Также существуют ограничения:

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

Типы криптографических ключей

Объекты CryptoKey содержат метаданные:

  • тип ключа (public/private/secret)
  • разрешённые операции
  • извлекаемость (extractable)
  • алгоритм использования

Пример структуры:

{
  type: "secret",
  extractable: false,
  algorithm: { name: "AES-GCM" },
  usages: ["encrypt", "decrypt"]
}

Алгоритмическая модель SubtleCrypto

Поддерживаемые алгоритмы делятся на категории:

Симметричные:

  • AES-CBC
  • AES-GCM
  • AES-KW

Асимметричные:

  • RSA-OAEP
  • RSA-PSS
  • ECDSA
  • ECDH

Хэш-функции:

  • SHA-256
  • SHA-384
  • SHA-512

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


Производственные особенности и ограничения исполнения

Криптографические операции выполняются вне основного потока JavaScript, что снижает влияние на производительность интерфейса, но накладывает особенности:

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

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


Работа с памятью и бинарными буферами

Все криптографические операции оперируют ArrayBuffer:

  • Uint8Array используется для представления байтов
  • преобразование строк выполняется через TextEncoder
  • результаты требуют явного декодирования

Пример преобразования:

const buffer = new Uint8Array([1, 2, 3]).buffer;

Ключевые ограничения архитектуры SubtleCrypto

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