В экосистеме JOSE (JSON Object Signing and Encryption) шифрование JWE (JSON Web Encryption) строится вокруг концепции гибридного шифрования: симметричный ключ используется для защиты данных, а асимметричный — для безопасной передачи этого ключа. Центральное место в практических реализациях занимает семейство алгоритмов AES, среди которых наиболее распространены AES-GCM и AES-CBC в комбинации с HMAC.
Структура JWE включает пять основных компонентов:
Алгоритмы шифрования в JOSE делятся на две категории:
AES-GCM и AES-CBC + HMAC относятся ко второй категории и отвечают за непосредственное шифрование полезной нагрузки.
AES-GCM (Galois/Counter Mode) представляет собой режим аутентифицированного шифрования (AEAD), объединяющий конфиденциальность и целостность данных в одном алгоритме.
AES-GCM одновременно формирует:
Наиболее часто используется:
A128GCMA192GCMA256GCMimport { CompactEncrypt, compactDecrypt } from 'jose'
import { generateKey } from 'jose/util/generate_key'
const key = await generateKey('A256GCM')
const encoder = new TextEncoder()
const jwe = await new CompactEncrypt(
encoder.encode('секретное сообщение')
)
.setProtectedHeader({ alg: 'dir', enc: 'A256GCM' })
.encrypt(key)
const { plaintext } = await compactDecrypt(jwe, key)
Особенность режима dir заключается в том, что CEK не
передаётся отдельно — он используется напрямую.
AES-CBC сам по себе обеспечивает только конфиденциальность, но не защищает от модификации данных. Для устранения этой проблемы в JOSE используется комбинированная схема:
Алгоритм A256CBC-HS512 является наиболее
распространённым представителем этой группы и включает:
Ключ фактически делится на две части:
Такой подход называется split key model.
Процесс шифрования включает следующие этапы:
Генерация случайного CEK
Разделение CEK на:
Шифрование данных через AES-CBC с IV
Вычисление HMAC:
Формирование authentication tag
import { CompactEncrypt, compactDecrypt } from 'jose'
const textEncoder = new TextEncoder()
const key = crypto.getRandomValues(new Uint8Array(64)) // 512 бит
const jwe = await new CompactEncrypt(
textEncoder.encode('данные для защиты')
)
.setProtectedHeader({ alg: 'dir', enc: 'A256CBC-HS512' })
.encrypt(key)
const { plaintext } = await compactDecrypt(jwe, key)
Здесь ключ должен иметь удвоенную длину относительно AES-части, поскольку он включает HMAC-компонент.
Библиотека jose строго следует спецификации RFC 7516 и
учитывает:
В заголовке JWE фиксируется используемая криптосхема:
{
"alg": "dir",
"enc": "A256GCM"
}
или
{
"alg": "dir",
"enc": "A256CBC-HS512"
}
Поле enc определяет именно алгоритм контентного
шифрования, включая способ аутентификации.
Критические требования при использовании AES-GCM:
Для AES-CBC + HMAC:
В JavaScript-экосистеме JOSE применяется для:
Алгоритмы AES-GCM и AES-CBC + HMAC формируют основу практической криптографии в этих сценариях, обеспечивая баланс между производительностью, совместимостью и криптостойкостью.