Расшифровка General JWE: generalDecrypt

В формате JWE (JSON Web Encryption) General Serialization поддерживается работа с несколькими получателями. Каждый получатель может иметь собственный зашифрованный ключ контента (CEK), при этом само зашифрованное содержимое остаётся единым. Расшифровка такого объекта требует выбора подходящего ключа среди возможных recipients и последующего восстановления plaintext.

В библиотеке jose для JavaScript этот процесс реализуется через функцию generalDecrypt.


Формат General JWE

General JWE представляет собой JSON-структуру следующего вида:

{
  "protected": "BASE64URL",
  "iv": "BASE64URL",
  "ciphertext": "BASE64URL",
  "tag": "BASE64URL",
  "aad": "BASE64URL",
  "recipients": [
    {
      "header": { "kid": "key1" },
      "encrypted_key": "BASE64URL"
    },
    {
      "header": { "kid": "key2" },
      "encrypted_key": "BASE64URL"
    }
  ]
}

Ключевая особенность — массив recipients, где каждый элемент содержит зашифрованный CEK для конкретного получателя.


Сигнатура generalDecrypt

generalDecrypt(key, jwe, options?)

Параметры функции

key Криптографический ключ, используемый для расшифровки CEK. Может быть:

  • KeyLike (CryptoKey, KeyObject)
  • JWK-совместимый ключ

jwe Объект General JWE, содержащий:

  • protected header
  • iv
  • ciphertext
  • tag
  • recipients

options (необязательно) Дополнительные параметры поведения:

  • crit — обработка критических параметров заголовка
  • contentEncryptionAlgorithms — допустимые алгоритмы
  • keyManagementAlgorithms — допустимые алгоритмы управления ключами

Результат выполнения

Функция возвращает объект:

{
  plaintext: Uint8Array,
  protectedHeader: object,
  additionalAuthenticatedData?: Uint8Array
}

Логика работы generalDecrypt

Процесс расшифровки General JWE включает несколько этапов:

1. Выбор подходящего recipient

Каждый элемент recipients проверяется на возможность расшифровки CEK с использованием предоставленного ключа.

Если ключ соответствует kid, alg или другим параметрам заголовка — recipient считается подходящим.


2. Расшифровка CEK

После выбора recipient выполняется:

  • расшифровка encrypted_key
  • получение Content Encryption Key (CEK)

3. Расшифровка ciphertext

С использованием CEK выполняется расшифровка:

  • ciphertext
  • проверка tag
  • использование iv
  • учёт protected header

4. Проверка целостности

Аутентификационный тег гарантирует:

  • неизменность ciphertext
  • соответствие заголовков
  • корректность алгоритма

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

import { generalDecrypt, importJWK } from 'jose'

const key = await importJWK({
  kty: 'RSA',
  e: 'AQAB',
  n: '...'
}, 'RSA-OAEP-256')

const jwe = {
  protected: 'eyJlbmMiOiJBMjU2R0NNIn0',
  iv: '48V1_ALb6US04U3b',
  ciphertext: '5eym8TW_c8Su...',
  tag: 'XFBoMYUZodetZdvTiFvSkQ',
  recipients: [
    {
      header: { alg: 'RSA-OAEP-256', kid: 'key-rsa-1' },
      encrypted_key: 'GawgguFyGrWKav7AX4VKUg'
    }
  ]
}

const { plaintext, protectedHeader } = await generalDecrypt(key, jwe)

console.log(new TextDecoder().decode(plaintext))

Работа с несколькими получателями

General JWE оптимален в сценариях:

  • рассылка одного сообщения разным клиентам
  • использование разных ключей доступа
  • гибридные системы шифрования (RSA + EC + symmetric keys)

generalDecrypt автоматически:

  • перебирает recipients
  • пробует расшифровать каждый encrypted_key
  • выбирает первый успешный вариант

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

В зависимости от ключа и конфигурации могут использоваться:

  • RSA-OAEP / RSA-OAEP-256
  • ECDH-ES
  • A256KW / A128KW
  • dir (direct encryption)

Алгоритм Content Encryption (CEK):

  • A256GCM
  • A128GCM
  • A256CBC-HS512

Особенности обработки заголовков

Protected header применяется ко всему JWE и содержит:

  • alg — алгоритм управления ключом
  • enc — алгоритм шифрования содержимого
  • дополнительные параметры

Unprotected header в General JWE может присутствовать в recipients[].header.

При расшифровке происходит объединение:

  • protected header
  • recipient header

Ошибки при расшифровке

Типичные причины исключений:

JWEDecryptionFailed

  • ключ не соответствует ни одному recipient
  • повреждён encrypted_key

JWEInvalid

  • некорректная структура JSON
  • отсутствуют обязательные поля

JOSENotSupported

  • неподдерживаемый alg или enc
  • отсутствие реализации алгоритма в runtime

Работа с KeyLike и JWK

generalDecrypt поддерживает:

  • CryptoKey (WebCrypto)
  • KeyObject (Node.js crypto)
  • JWK через importJWK

Важно, чтобы ключ соответствовал алгоритму recipient.


Внутренние особенности реализации

В jose библиотеке:

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

Практические сценарии использования

General JWE и generalDecrypt применяются в системах:

  • распределённой авторизации
  • multi-tenant API платформ
  • защищённой доставки сообщений
  • enterprise messaging
  • гибридных криптосистемах

Структура General JWE позволяет масштабировать шифрование без дублирования payload.