Алгоритмическая модель JWE в jose строится вокруг разделения ответственности между управлением ключами и шифрованием содержимого. В отличие от подписанных JWT (JWS), где цель — обеспечить целостность и аутентичность, зашифрованный JWT (JWE) решает задачу конфиденциальности, скрывая payload от любых сторон, кроме получателя.
В спецификации JWE всегда участвуют два уровня криптографии:
В библиотеке jose выбор этих алгоритмов напрямую влияет на безопасность, производительность и совместимость системы.
Выбор алгоритма в JWE всегда начинается не с библиотеки, а с модели угроз. Основные сценарии, которые определяют конфигурацию:
Если эти параметры не определены, выбор алгоритма становится произвольным, что приводит либо к избыточной криптографии, либо к ослаблению безопасности.
В jose поддерживается несколько устойчивых комбинаций, которые считаются стандартными:
Наиболее распространённая схема в корпоративных системах:
Характеристики:
Недостатки:
Используется в сценариях, где инфраструктура построена вокруг сертификатов и публичных ключей.
Более современный подход на эллиптических кривых:
Характеристики:
Особенность заключается в том, что ключ шифрования не передаётся, а вычисляется на обеих сторонах.
В jose это один из предпочтительных вариантов для современных систем обмена токенами.
Схема с прямым симметричным ключом:
Здесь отсутствует обёртка ключа — один и тот же секрет используется напрямую.
Характеристики:
Недостатки:
Используется в замкнутых системах, например между микросервисами внутри одного доверенного контура.
Большинство современных конфигураций jose используют AES-GCM, чаще всего A256GCM.
Причины:
В JWE этот алгоритм одновременно:
Ошибка выбора режима без AEAD (например CBC без HMAC) приводит к уязвимостям типа padding oracle.
Однако:
Особенность jose заключается в том, что ECDH-ES позволяет строить гибридные схемы, где каждый JWT имеет уникальный session key.
JWE в jose строится из пяти основных компонентов:
Алгоритм управления ключом определяет, будет ли encrypted key присутствовать и как он формируется.
import { EncryptJWT, jwtDecrypt, generateKeyPair } from 'jose'
const { publicKey, privateKey } = await generateKeyPair('RSA-OAEP-256')
const jwt = await new EncryptJWT({ userId: 123, role: 'admin' })
.setProtectedHeader({ alg: 'RSA-OAEP-256', enc: 'A256GCM' })
.setIssuedAt()
.setExpirationTime('2h')
.encrypt(publicKey)
const decrypted = await jwtDecrypt(jwt, privateKey)
В этой схеме payload полностью недоступен без приватного ключа, а симметричный ключ генерируется для каждого токена отдельно.
import { EncryptJWT, jwtDecrypt, generateKeyPair } from 'jose'
const { publicKey, privateKey } = await generateKeyPair('ECDH-ES')
const jwt = await new EncryptJWT({ scope: 'read:messages' })
.setProtectedHeader({ alg: 'ECDH-ES', enc: 'A256GCM' })
.encrypt(publicKey)
const payload = await jwtDecrypt(jwt, privateKey)
Здесь отсутствует передача зашифрованного ключа — он вычисляется на основе обмена эллиптическими параметрами.
import { EncryptJWT, jwtDecrypt } from 'jose'
import { createSecretKey } from 'crypto'
const key = createSecretKey(Buffer.from('32bytes-long-secret-key-................'))
const jwt = await new EncryptJWT({ data: 'secure' })
.setProtectedHeader({ alg: 'dir', enc: 'A256GCM' })
.encrypt(key)
const decoded = await jwtDecrypt(jwt, key)
Такая модель требует строгого контроля хранения ключа, так как компрометация полностью раскрывает все токены.
Алгоритмы JWE можно условно разделить по нагрузке:
В высоконагруженных API часто наблюдается переход от RSA к ECDH-ES именно из-за стоимости операций при масштабировании.
В jose идентификатор ключа (kid) играет критическую роль в управлении несколькими ключами одновременно.
Структура header:
{
"alg": "RSA-OAEP-256",
"enc": "A256GCM",
"kid": "key-2026-01"
}
Использование kid позволяет:
Ошибка отсутствия стратегии ротации приводит к необходимости массового ре-шифрования всех токенов при смене ключа.
Некоторые сценарии требуют шифрования одного JWT для нескольких получателей. В этом случае:
В jose multi-recipient модель увеличивает размер токена пропорционально количеству получателей, что важно учитывать при проектировании API.
На практике встречаются повторяющиеся ошибки:
Особенно критична ошибка повторного использования IV в GCM, так как она приводит к частичному восстановлению plaintext.
В прикладных системах выбор обычно сводится к следующим профилям:
Архитектура системы определяет не только алгоритм, но и модель жизненного цикла ключей, что в jose является центральным аспектом безопасности JWE.