Объект window.crypto и его структура

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

Структурно window.crypto состоит из двух ключевых компонентов:

  • crypto.getRandomValues()
  • crypto.subtle

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


Общая структура объекта crypto

Базовая форма объекта выглядит следующим образом:

window.crypto = {
  getRandomValues,
  subtle
}

Важно понимать, что crypto является неизменяемым объектом. Его нельзя переопределить или расширить через присваивание новых свойств в строгом режиме.


crypto.getRandomValues

Метод getRandomValues() используется для генерации криптографически стойких случайных чисел. Он работает с типизированными массивами и заполняет их случайными значениями.

Сигнатура

crypto.getRandomValues(typedArray)

Поддерживаемые типы массивов

  • Uint8Array
  • Uint16Array
  • Uint32Array
  • BigUint64Array

Поведение

Метод не возвращает новый массив. Он изменяет переданный объект напрямую.

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

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


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

Существует несколько строгих ограничений:

  • нельзя использовать Array или Float32Array
  • максимальный размер буфера ограничен реализацией браузера (обычно до 65536 байт за вызов)
  • значения всегда равномерно распределены в пределах диапазона типа

crypto.subtle — ядро Web Crypto API

crypto.subtle (SubtleCrypto) — это основной интерфейс для криптографических операций. Он предоставляет набор асинхронных методов, возвращающих Promise.

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

  • все операции выполняются асинхронно
  • доступен только в secure context
  • не раскрывает внутренние детали реализации (отсюда “subtle”)
  • работает с бинарными данными через ArrayBuffer и TypedArray

Структура SubtleCrypto

Объект crypto.subtle включает следующие группы методов:

1. Хеширование

  • digest()

2. Генерация ключей

  • generateKey()

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

  • importKey()
  • exportKey()

4. Шифрование и дешифрование

  • encrypt()
  • decrypt()

5. Подпись и проверка подписи

  • sign()
  • verify()

6. Обёртывание ключей

  • wrapKey()
  • unwrapKey()

digest — вычисление хеша

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

Сигнатура

crypto.subtle.digest(algorithm, data)

Пример алгоритмов

  • "SHA-1"
  • "SHA-256"
  • "SHA-384"
  • "SHA-512"

Пример использования

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

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

Результат — ArrayBuffer, содержащий хеш.


generateKey — генерация ключей

Метод generateKey создаёт криптографические ключи для симметричных и асимметричных алгоритмов.

Сигнатура

crypto.subtle.generateKey(algorithm, extractable, keyUsages)

Типы алгоритмов

  • AES (AES-GCM, AES-CBC, AES-KW)
  • RSA (RSA-OAEP, RSASSA-PKCS1-v1_5)
  • ECDSA / ECDH

Пример

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

Параметры

  • extractable — можно ли экспортировать ключ
  • keyUsages — допустимые операции

importKey и exportKey

importKey

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

crypto.subtle.importKey(format, keyData, algorithm, extractable, usages)

Форматы:

  • "raw"
  • "pkcs8"
  • "spki"
  • "jwk"

exportKey

Позволяет получить ключ в экспортируемом виде.

crypto.subtle.exportKey(format, key)

encrypt и decrypt

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

encrypt

crypto.subtle.encrypt(algorithm, key, data)

decrypt

crypto.subtle.decrypt(algorithm, key, data)

Пример AES-GCM

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

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

sign и verify

Используются для цифровых подписей.

sign

crypto.subtle.sign(algorithm, key, data)

verify

crypto.subtle.verify(algorithm, key, signature, data)

Алгоритмы

  • RSASSA-PKCS1-v1_5
  • ECDSA
  • HMAC

wrapKey и unwrapKey

wrapKey

Шифрует ключ другим ключом.

crypto.subtle.wrapKey(format, key, wrappingKey, algorithm)

unwrapKey

Расшифровывает и восстанавливает ключ.

crypto.subtle.unwrapKey(format, wrappedKey, unwrappingKey, algorithm, unwrappedKeyAlgorithm, extractable, keyUsages)

Внутренняя модель объекта crypto

С точки зрения архитектуры браузера, window.crypto является связующим слоем между JavaScript и нативной криптографической реализацией операционной системы.

Структурно можно представить так:

window
  └── crypto
       ├── getRandomValues()
       └── subtle
            ├── digest()
            ├── generateKey()
            ├── importKey()
            ├── exportKey()
            ├── encrypt()
            ├── decrypt()
            ├── sign()
            ├── verify()
            ├── wrapKey()
            └── unwrapKey()

Особенности выполнения операций

Все методы subtle возвращают Promise, что связано с несколькими факторами:

  • криптографические операции выполняются вне основного потока
  • используется нативная реализация (C/C++/OS API)
  • предотвращается блокировка UI

Форматы данных

Web Crypto API не работает со строками напрямую. Все входные и выходные данные должны быть в бинарном формате:

  • ArrayBuffer
  • TypedArray

Для преобразования используется:

  • TextEncoder
  • TextDecoder

Безопасный контекст выполнения

window.crypto доступен только при следующих условиях:

  • HTTPS соединение
  • localhost (исключение для разработки)

При открытии через http объект crypto.subtle может быть недоступен или частично ограничен.


Иммутабельность и защита API

Объект crypto защищён от модификации:

  • свойства нельзя удалить
  • нельзя переопределить методы
  • объект не расширяется через prototype chain

Это сделано для предотвращения подмены криптографических функций.


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

Поддержка алгоритмов зависит от браузера, но обычно включает:

  • SHA семейство
  • AES-GCM как основной симметричный алгоритм
  • RSA-OAEP для шифрования
  • ECDSA для подписей
  • HMAC для аутентификации сообщений

Взаимодействие crypto и SubtleCrypto

crypto выполняет роль контейнера, а subtle — вычислительного ядра.

Разделение функций:

  • crypto.getRandomValues() — генерация случайных чисел
  • crypto.subtle — криптографические операции высокого уровня

Такое разделение позволяет отделить простые операции от вычислительно сложных.


Типичные ошибки при работе с crypto

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