Прямое шифрование: dir

В режиме прямого шифрования JWE (alg: dir) используется симметричный ключ, который одновременно применяется для шифрования и расшифрования полезной нагрузки без промежуточного механизма обёртки ключа. В отличие от схем с RSA или ECDH, здесь отсутствует этап передачи или защиты ключа-шифровщика: один и тот же секретный ключ целиком отвечает за криптографическую безопасность сообщения.

Алгоритм dir в спецификации JWE (JSON Web Encryption) относится к категории direct encryption, где:

  • отсутствует ключ-шифрования контента (CEK wrapping key);
  • заранее согласованный симметричный ключ используется напрямую;
  • CEK фактически равен внешнему ключу шифрования;
  • защита обеспечивается только качеством и секретностью симметричного ключа.

Формально процесс выглядит так:

  1. выбирается симметричный ключ фиксированной длины;
  2. этот ключ используется как Content Encryption Key (CEK);
  3. данные шифруются алгоритмом enc (например, A256GCM);
  4. результат собирается в структуру JWE Compact Serialization.

Требования к ключу

При использовании dir критически важно соблюдение требований к длине и типу ключа.

Для различных алгоритмов enc требуются ключи соответствующего размера:

  • A128GCM → 16 байт (128 бит)
  • A192GCM → 24 байта (192 бита)
  • A256GCM → 32 байта (256 бит)

Несоответствие длины ключа приводит к ошибкам на этапе криптографической проверки или генерации.

Ключ должен быть:

  • криптографически случайным;
  • неизменяемым после распределения;
  • защищённым на уровне хранения (env, vault, HSM).

Структура JWE при использовании dir

JWE Compact Serialization при dir имеет следующую форму:

BASE64URL(Protected Header).
BASE64URL(Encrypted Key - пусто).
BASE64URL(IV).
BASE64URL(Ciphertext).
BASE64URL(Authentication Tag)

Особенность dir:

  • второй сегмент (Encrypted Key) всегда пуст;
  • ключ не передаётся, так как он уже известен обеим сторонам.

Пример заголовка:

{
  "alg": "dir",
  "enc": "A256GCM"
}

Реализация в Jose

Библиотека Jose в JavaScript предоставляет высокоуровневый API для работы с JWE.

Основные модули:

  • jose/jwe/compact/encrypt
  • jose/jwe/compact/decrypt
  • jose/util/generate_secret

Установка ключа

Симметричный ключ создаётся через криптографически безопасный генератор:

import { generateSecret } from 'jose'

const key = await generateSecret('A256GCM')

Внутри создаётся CryptoKey, совместимый с Web Crypto API.

Шифрование данных

Процесс шифрования с dir выглядит следующим образом:

import { CompactEncrypt } from 'jose'

const secret = await generateSecret('A256GCM')

const encoder = new TextEncoder()

const jwe = await new CompactEncrypt(
  encoder.encode('Секретные данные')
)
  .setProtectedHeader({
    alg: 'dir',
    enc: 'A256GCM'
  })
  .encrypt(secret)

В этом процессе:

  • CompactEncrypt формирует JWE структуру;
  • заголовок фиксирует использование dir;
  • encrypt(secret) применяет симметричный ключ напрямую;
  • результат — компактная строка JWE.

Расшифрование данных

Расшифрование выполняется симметрично:

import { compactDecrypt } from 'jose'

const { plaintext } = await compactDecrypt(jwe, secret)

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

Внутренний процесс:

  • извлекается IV и ciphertext;
  • используется тот же ключ secret;
  • выполняется проверка authentication tag;
  • возвращается исходный plaintext.

Криптографическая модель безопасности

В dir отсутствует асимметричное распределение ключей, поэтому безопасность полностью зависит от:

  • секретности общего ключа;
  • отсутствия утечек в runtime;
  • корректного хранения ключа.

Модель угроз:

  • компрометация ключа → полная компрометация всех сообщений;
  • повторное использование ключа допустимо, но рискованно при слабой изоляции контекстов;
  • отсутствие ротации ключей увеличивает поверхность атаки.

Особенности использования в архитектуре

dir применяется в случаях, где:

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

Типичные сценарии:

  • внутренние API между микросервисами;
  • шифрование конфигураций;
  • защищённые каналы внутри одного домена доверия.

Частые ошибки при использовании dir

Несоответствие длины ключа

Использование ключа неправильного размера приводит к ошибкам вида:

  • invalid key length
  • operation not supported

Попытка использовать публичные ключи

dir несовместим с RSA/ECDH ключевыми структурами.

Хранение ключа в коде

Прямое встраивание ключа в исходный код делает систему криптографически бессмысленной.

Взаимодействие alg и enc

В JWE всегда действует связка:

  • alg: dir — способ обращения с ключом
  • enc: A256GCM — алгоритм шифрования контента

Важно, что:

  • alg не выполняет шифрование данных;
  • enc отвечает за AES-GCM или аналогичный алгоритм;
  • безопасность определяется именно enc и качеством ключа.

Внутренние этапы AES-GCM в Jose

При использовании A256GCM выполняются:

  • генерация nonce (IV);
  • AES-CTR шифрование данных;
  • вычисление authentication tag;
  • связывание AAD (Additional Authenticated Data) с заголовком JWE.

Это обеспечивает:

  • конфиденциальность;
  • целостность;
  • защиту от подмены заголовка.

Поведение при декодировании

При расшифровке Jose выполняет строгую валидацию:

  • проверка совпадения alg;
  • проверка enc;
  • проверка длины ключа;
  • проверка authentication tag.

Любое несоответствие приводит к ошибке без раскрытия частичных данных.

Производительность

dir является одной из самых быстрых схем JWE:

  • отсутствует RSA/ECDH вычисление;
  • нет операций асимметричного шифрования;
  • используется только симметричный AES-GCM.

Это делает его предпочтительным для high-throughput систем.

Ограничения модели dir

Несмотря на простоту, существуют ограничения:

  • невозможность безопасного обмена ключом через небезопасный канал;
  • отсутствие масштабируемости в открытых системах;
  • необходимость строгого контроля жизненного цикла ключа;
  • невозможность использования с публичными клиентами без предварительного секретного обмена.

Практическая структура данных JWE

Пример итоговой строки:

eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIn0..
[IV].
[Ciphertext].
[Tag]

Второй сегмент всегда пустой, что визуально отличает dir от других режимов.

Поведение в Node.js окружении

Jose использует Web Crypto API, поэтому:

  • в Node.js требуется поддержка crypto.webcrypto;
  • ключи представлены как CryptoKey;
  • операции выполняются асинхронно;
  • бинарные данные строго типизированы через Uint8Array.

Рекомендации по эксплуатации

При работе с dir ключевой аспект — управление секретом:

  • хранение в переменных окружения или secret manager;
  • регулярная ротация ключей;
  • изоляция ключей по окружениям (dev/stage/prod);
  • ограничение доступа к runtime.

Также важно:

  • фиксировать алгоритмы alg и enc;
  • избегать динамического выбора криптопараметров;
  • контролировать совместимость версий Jose.