Понятие extractable и usages у ключей

В Web Crypto API каждый ключ (CryptoKey) обладает свойством, определяющим возможность его извлечения из криптографического контекста:

extractable: boolean

Это логический флаг, который задаётся при создании или импорте ключа и определяет, можно ли экспортировать ключевое значение наружу через crypto.subtle.exportKey.

Поведение extractable

  • extractable: true Ключ может быть экспортирован в поддерживаемые форматы (например, spki, pkcs8, jwk).
  • extractable: false Ключ становится неизвлекаемым: попытка экспорта приводит к ошибке OperationError.

Практическое значение

Основная задача параметра — контроль утечек криптографического материала:

  • защита приватных ключей от извлечения через JavaScript
  • снижение риска компрометации при XSS-атаках
  • реализация модели «ключ существует только внутри браузера»

Пример генерации неизвлекаемого ключа

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

Попытка экспорта:

await crypto.subtle.exportKey("raw", key);

Приведёт к исключению.

Связь extractable и безопасности

Неизвлекаемые ключи усиливают модель защиты, но вводят ограничения:

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

Поэтому выбор значения зависит от архитектуры:

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

Параметр usages: ограничение допустимых операций над ключом

Свойство usages определяет, какие криптографические операции разрешены для конкретного ключа.

Это массив строк, фиксируемый при создании или импорте ключа:

usages: ["encrypt", "decrypt"]

Web Crypto API использует этот механизм как встроенную политику доступа.

Основные значения usages

Симметричные операции

  • "encrypt" — разрешено шифрование
  • "decrypt" — разрешено расшифрование
  • "wrapKey" — упаковка ключей
  • "unwrapKey" — распаковка ключей

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

  • "sign" — создание цифровой подписи
  • "verify" — проверка подписи
  • "deriveKey" — вывод ключа
  • "deriveBits" — получение битового материала

Жёсткость ограничения

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

Пример:

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

await crypto.subtle.decrypt(
  { name: "AES-GCM", iv },
  key,
  data
);

Результат — ошибка, так как "decrypt" отсутствует в usages.

Механизм проверки

Проверка выполняется браузером на уровне Web Crypto API до выполнения операции. Это не логическое соглашение, а встроенное ограничение исполнения.


Взаимосвязь extractable и usages

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

crypto.subtle.generateKey(
  algorithm,
  extractable,
  usages
);

Независимость параметров

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

Они не влияют друг на друга напрямую.

Типичные комбинации

Высокая безопасность (локальные ключи)

extractable: false,
usages: ["encrypt", "decrypt"]

Характеристика:

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

Обмен и переносимость

extractable: true,
usages: ["sign"]

Характеристика:

  • ключ можно экспортировать
  • используется для передачи или резервного копирования

Серверная совместимость

extractable: true,
usages: ["encrypt", "decrypt", "wrapKey"]

Характеристика:

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

Поведение при ошибках конфигурации

Несоответствие usages и операции

Если операция не входит в список usages, API возвращает InvalidAccessError.

Попытка экспорта при extractable: false

Возникает:

  • OperationError

Влияние на deriveKey и deriveBits

Для производных ключей критично корректное указание:

usages: ["deriveKey", "deriveBits"]

Отсутствие одного из значений блокирует соответствующий метод.


Ограничения и особенности реализации

Статичность параметров

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

  • extractable нельзя изменить
  • usages нельзя изменить

Ключ становится неизменяемым объектом политики доступа.

Различия между алгоритмами

Некоторые алгоритмы игнорируют часть usages, но Web Crypto API всё равно требует их корректного указания.

JWK и влияние usages

При импорте/экспорте через JWK поле "key_ops" синхронизируется с usages.


Типовые ошибки при работе с extractable и usages

Слишком широкие права

usages: ["encrypt", "decrypt", "sign", "verify"]

Проблема: нарушение принципа минимальных привилегий.

Отсутствие нужной операции

Ключ создан, но операция не выполняется из-за отсутствия "decrypt" или "sign".

Попытка экспорта защищённого ключа

extractable: false часто приводит к неожиданным ошибкам при интеграции с внешними системами.


Рекомендации по проектированию ключей

  • минимизировать список usages до строго необходимого
  • использовать extractable: false для ключей хранения и шифрования локальных данных
  • разделять ключи по назначению (encrypt/decrypt и sign/verify не смешивать)
  • избегать универсальных ключей с полным набором операций

Архитектурное значение параметров

extractable и usages формируют основу модели безопасности Web Crypto API:

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

Эти параметры превращают ключ не просто в бинарный объект, а в строго ограниченный криптографический ресурс с фиксированной политикой использования