В формате JWE (JSON Web Encryption) General Serialization поддерживается работа с несколькими получателями. Каждый получатель может иметь собственный зашифрованный ключ контента (CEK), при этом само зашифрованное содержимое остаётся единым. Расшифровка такого объекта требует выбора подходящего ключа среди возможных recipients и последующего восстановления plaintext.
В библиотеке jose для JavaScript этот процесс
реализуется через функцию generalDecrypt.
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 для конкретного получателя.
generalDecryptgeneralDecrypt(key, jwe, options?)
key Криптографический ключ, используемый для расшифровки CEK. Может быть:
KeyLike (CryptoKey, KeyObject)jwe Объект General JWE, содержащий:
options (необязательно) Дополнительные параметры поведения:
crit — обработка критических параметров заголовкаcontentEncryptionAlgorithms — допустимые алгоритмыkeyManagementAlgorithms — допустимые алгоритмы
управления ключамиФункция возвращает объект:
{
plaintext: Uint8Array,
protectedHeader: object,
additionalAuthenticatedData?: Uint8Array
}
generalDecryptПроцесс расшифровки General JWE включает несколько этапов:
Каждый элемент recipients проверяется на возможность
расшифровки CEK с использованием предоставленного ключа.
Если ключ соответствует kid, alg или другим
параметрам заголовка — recipient считается подходящим.
После выбора recipient выполняется:
encrypted_keyС использованием CEK выполняется расшифровка:
ciphertexttagivprotected headerАутентификационный тег гарантирует:
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 оптимален в сценариях:
generalDecrypt автоматически:
encrypted_keyВ зависимости от ключа и конфигурации могут использоваться:
Алгоритм Content Encryption (CEK):
Protected header применяется ко всему JWE и содержит:
alg — алгоритм управления ключомenc — алгоритм шифрования содержимогоUnprotected header в General JWE может присутствовать в
recipients[].header.
При расшифровке происходит объединение:
Типичные причины исключений:
JWEDecryptionFailed
JWEInvalid
JOSENotSupported
generalDecrypt поддерживает:
CryptoKey (WebCrypto)KeyObject (Node.js crypto)importJWKВажно, чтобы ключ соответствовал алгоритму recipient.
В jose библиотеке:
General JWE и generalDecrypt применяются в системах:
Структура General JWE позволяет масштабировать шифрование без дублирования payload.