AES и его режимы работы в контексте Jose

AES (Advanced Encryption Standard) представляет собой симметричный алгоритм шифрования, который лежит в основе большинства современных криптографических протоколов. В контексте веб-экосистемы JavaScript он активно используется через JWE (JSON Web Encryption), а библиотека Jose реализует высокоуровневый интерфейс для работы с криптографическими примитивами, включая AES в различных режимах.

В спецификации JSON Web Encryption данные шифруются по многоступенчатой схеме:

  1. Генерация контентного ключа (CEK — Content Encryption Key)
  2. Шифрование полезной нагрузки с использованием AES
  3. Защита ключа (key management)
  4. Формирование компактного JWE-токена

AES отвечает за этап непосредственного шифрования payload. В Jose это реализуется через набор алгоритмов, которые определяются параметром enc.

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

  • alg — алгоритм управления ключами (например, RSA-OAEP, ECDH-ES, direct)
  • enc — алгоритм симметричного шифрования (AES-GCM, AES-CBC + HMAC)

Поддерживаемые AES-режимы в Jose

В библиотеке Jose используются стандартизированные режимы AES, описанные в RFC 7518.

AES-GCM (Galois/Counter Mode)

Наиболее современный и рекомендуемый режим:

  • A128GCM
  • A192GCM
  • A256GCM

GCM объединяет шифрование и аутентификацию данных. Это означает, что помимо конфиденциальности обеспечивается целостность.

Особенности:

  • Один проход шифрования
  • Встроенная аутентификация (AEAD)
  • Высокая производительность
  • Поддержка параллельной обработки блоков

В Jose использование AES-GCM выглядит следующим образом:

import { generateKey, EncryptJWT, jwtDecrypt } from 'jose'

const key = await generateKey('A256GCM')

const token = await new EncryptJWT({ userId: 123 })
  .setProtectedHeader({ alg: 'dir', enc: 'A256GCM' })
  .setIssuedAt()
  .setExpirationTime('2h')
  .encrypt(key)

const { payload } = await jwtDecrypt(token, key)

Режим dir указывает, что ключ используется напрямую как CEK, без дополнительной обёртки.

AES-CBC с HMAC (конкатенированная схема)

До появления GCM широко использовалась комбинация:

  • AES-CBC для шифрования
  • HMAC-SHA2 для аутентификации

В Jose это представлено как:

  • A128CBC-HS256
  • A192CBC-HS384
  • A256CBC-HS512

Структура алгоритма разделяет ключ на две части:

  • половина для AES
  • половина для HMAC

Это обеспечивает разделение криптографических обязанностей: конфиденциальность и целостность реализуются независимо.

Особенности CBC-HMAC:

  • Два прохода обработки (шифрование + MAC)
  • Более высокая вычислительная стоимость
  • Устойчивость к ряду атак при корректной реализации
  • Историческая значимость и широкая совместимость

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

import { EncryptJWT } from 'jose'
import { createSecretKey } from 'crypto'

const key = createSecretKey(Buffer.from('your-256-bit-secret-key-your-256-bit-secret'))

const token = await new EncryptJWT({ role: 'admin' })
  .setProtectedHeader({ alg: 'dir', enc: 'A256CBC-HS512' })
  .setIssuedAt()
  .setExpirationTime('1h')
  .encrypt(key)

Режим direct (dir) и его влияние на AES

Алгоритм dir не выполняет шифрование ключа. Вместо этого:

  • CEK совпадает с предоставленным секретом
  • AES используется напрямую для шифрования payload

Это упрощает процесс, но требует строгого контроля ключей. Любая утечка секрета полностью компрометирует данные.

В контексте AES это означает:

  • отсутствие key wrapping
  • прямое использование ключа как входного материала для AES

Управление ключами AES в Jose

AES-ключи в Jose могут быть представлены в нескольких формах:

  • симметричные секреты (Buffer, Uint8Array)
  • CryptoKey (Web Crypto API)
  • JWK (JSON Web Key)

Генерация ключей:

import { generateKey } from 'jose'

const key = await generateKey('A256GCM')

Для ручного создания ключей:

import { createSecretKey } from 'crypto'

const key = createSecretKey(Buffer.from('32-bytes-long-secret-key........'))

Важно учитывать:

  • длина ключа строго соответствует выбранному AES-режиму
  • для A256 требуется 256-битный ключ
  • неправильная длина приводит к ошибке на этапе инициализации

IV и nonce в AES-GCM и CBC

AES-GCM

Использует nonce (обычно 96 бит):

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

Jose генерирует nonce автоматически при вызове .encrypt()

AES-CBC

Использует IV (Initialization Vector):

  • фиксированный размер 16 байт
  • должен быть случайным и уникальным
  • не требует уникальности в глобальном масштабе, но критичен для каждой операции

Дополнительные аутентифицированные данные (AAD)

AES-GCM поддерживает AAD (Additional Authenticated Data), которые не шифруются, но участвуют в проверке целостности.

В Jose AAD формируется из:

  • JWE Protected Header
  • дополнительных параметров при конфигурации

Это обеспечивает защиту структуры токена от подмены.

Формат JWE и размещение AES-данных

Компактный JWE состоит из пяти частей:

protectedHeader.encryptedKey.iv.ciphertext.tag

В AES-режимах:

  • ciphertext — результат AES-шифрования
  • tag — аутентификационный тег (AES-GCM или CBC-HMAC)

Пример структуры:

eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIn0
.
.
48V1_ALb6US04U3b
.
5eym8TW_c8SuK0lt
.
XFBoMYUZodetZdvTiFvSkQ

Производительность AES в разных режимах

AES-GCM

  • оптимизирован под современные CPU
  • поддерживает аппаратное ускорение (AES-NI)
  • минимальная задержка

AES-CBC-HMAC

  • требует двойной обработки
  • более затратен по CPU
  • используется в legacy-системах

Типичные ошибки при работе с AES в Jose

Повторное использование nonce

В AES-GCM это приводит к:

  • утечке информации о plaintext
  • возможной полной компрометации ключа

Неверная длина ключа

  • A128 требует 128 бит
  • A256 требует 256 бит
  • несоответствие вызывает runtime error

Использование слабых секретов

  • строки вместо криптографически стойких ключей
  • отсутствие генерации через CSPRNG

Безопасные практики использования AES через Jose

  • использование generateKey вместо ручных строк
  • предпочтение AES-GCM как основного режима
  • изоляция ключей от бизнес-логики
  • регулярная ротация ключей
  • хранение секретов в secure storage (env vault, KMS)

Сравнение AES-GCM и AES-CBC-HMAC в Jose

AES-GCM:

  • единый алгоритм AEAD
  • высокая производительность
  • современный стандарт

AES-CBC-HMAC:

  • разделённая модель безопасности
  • совместимость с устаревшими системами
  • более сложная реализация

Выбор режима в Jose обычно определяется требованиями совместимости, а не предпочтениями разработчика, поскольку современные системы почти полностью перешли на GCM.

Взаимодействие AES с другими частями Jose

AES в Jose не существует изолированно. Он тесно связан с:

  • ECDH-ES (выработка ключа через эллиптические кривые)
  • RSA-OAEP (обёртка ключа)
  • PBES2 (парольное шифрование ключа)

В этих схемах AES выступает конечным слоем, обеспечивающим защиту данных после доставки CEK.

В результате архитектура Jose формирует многослойную модель, где AES является центральным механизмом конфиденциальности полезной нагрузки.