Метод subtle.wrapKey

Метод crypto.subtle.wrapKey используется для «обёртывания» (wrapping) криптографического ключа с помощью другого ключа. В результате исходный ключ преобразуется в зашифрованный формат, пригодный для безопасного хранения или передачи. Операция выполняется в рамках Web Crypto API и относится к низкоуровневым криптографическим примитивам, предоставляемым браузером.

Ключевая особенность механизма заключается в том, что сам ключ не экспортируется в открытом виде, а преобразуется в защищённый бинарный контейнер. Для обратной операции применяется crypto.subtle.unwrapKey.


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

Метод возвращает Promise, который резолвится в ArrayBuffer, содержащий зашифрованное представление ключа.


Параметры

format Строка, определяющая формат экспорта ключа перед его шифрованием. Возможные значения:

  • "raw" — сырое представление ключа
  • "pkcs8" — приватный ключ в формате PKCS#8
  • "spki" — публичный ключ в формате SubjectPublicKeyInfo
  • "jwk" — JSON Web Key

Выбор формата зависит от типа ключа и последующего использования.


key Экспортируемый ключ (CryptoKey), который требуется обернуть. Важные условия:

  • extractable должен быть установлен в true
  • ключ должен поддерживать экспорт в выбранном формате
  • тип ключа (приватный или симметричный) влияет на допустимый формат

wrappingKey Криптографический ключ (CryptoKey), используемый для шифрования исходного ключа. Этот ключ должен:

  • иметь назначение wrapKey
  • поддерживать выбранный алгоритм обёртывания
  • быть корректно импортирован или сгенерирован через crypto.subtle.generateKey

wrapAlgo Объект, определяющий алгоритм обёртывания ключа. Например:

  • {"name": "AES-KW"} — AES Key Wrap (RFC 3394)
  • {"name": "RSA-OAEP"} — RSA с оптимальным асимметричным шифрованием
  • дополнительные параметры могут включать hash для RSA-OAEP

Алгоритмы обёртывания

AES-KW

Алгоритм AES Key Wrap предназначен специально для защиты ключей. Он обеспечивает высокую производительность и криптографическую надёжность при симметричном подходе.

Особенности:

  • требует AES-ключ фиксированной длины (128, 192 или 256 бит)
  • не используется для произвольных данных, только для ключей
  • обеспечивает целостность и конфиденциальность

RSA-OAEP

Асимметричный механизм обёртывания, использующий пару ключей.

Особенности:

  • используется публичный ключ для обёртывания
  • приватный ключ используется для восстановления
  • требует указания хэш-функции (например, SHA-256)

Форматы ключей

raw

Используется для симметричных ключей, например AES. Представляет собой бинарный массив.

pkcs8

Применяется для приватных ключей. Часто используется при работе с RSA или ECDSA.

spki

Используется для публичных ключей. Подходит для передачи открытых ключей между системами.

jwk

JSON-формат, удобный для веб-приложений и REST API.


Пример: обёртывание AES ключа с помощью AES-KW

const wrappingKey = await crypto.subtle.generateKey(
  {
    name: "AES-KW",
    length: 256
  },
  true,
  ["wrapKey", "unwrapKey"]
);

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

const wrappedKey = await crypto.subtle.wrapKey(
  "raw",
  keyToWrap,
  wrappingKey,
  "AES-KW"
);

Пример: обёртывание RSA приватного ключа

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

const wrappedPrivateKey = await crypto.subtle.wrapKey(
  "pkcs8",
  rsaKeys.privateKey,
  rsaKeys.publicKey,
  {
    name: "RSA-OAEP",
    hash: "SHA-256"
  }
);

Важные ограничения и требования

Ключ, который передаётся в wrapKey, должен соответствовать нескольким условиям:

  • extractable: true, иначе операция завершится ошибкой
  • наличие разрешения wrapKey
  • совместимость формата с типом ключа
  • соответствие алгоритма обёртывания

Нарушение любого из условий приводит к InvalidAccessError.


Связь с unwrapKey

Операция обёртывания всегда предполагает обратимость:

  • wrapKey — преобразует ключ в зашифрованный формат
  • unwrapKey — восстанавливает исходный CryptoKey

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

  • алгоритм обёртывания
  • алгоритм исходного ключа
  • права использования ключа (keyUsages)
  • формат исходного ключа

Типичные сценарии использования

Обёртывание ключей применяется в следующих случаях:

  • хранение ключей в IndexedDB в защищённом виде
  • передача ключей между клиентами и сервером
  • построение иерархий ключей (key hierarchy)
  • реализация secure enclave-подобных схем на уровне приложения

Ошибки и поведение

Распространённые причины ошибок:

  • попытка обернуть неэкспортируемый ключ
  • несовместимость алгоритмов (например, RSA ключ с AES-KW)
  • отсутствие wrapKey в keyUsages
  • неправильный формат (pkcs8 для симметричного ключа)

При возникновении ошибки Promise отклоняется с соответствующим DOMException.


Криптографическая модель

Операция wrapKey является частью модели «key encapsulation»:

  • ключи считаются первичными объектами, а не данными
  • доступ к ним контролируется браузером
  • экспорт и упаковка выполняются только при явном разрешении
  • алгоритм обёртывания определяет уровень безопасности всей схемы

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