EnvelopedData: структура

Общая концепция CMS EnvelopedData

EnvelopedData является одной из базовых структур стандарта CMS (Cryptographic Message Syntax), описанного в RFC 5652. В контексте Jsrsasign эта структура используется для реализации гибридного шифрования: симметричный ключ шифрует данные, а сам симметричный ключ защищается асимметричным шифрованием для одного или нескольких получателей.

Архитектура EnvelopedData строится вокруг принципа разделения ответственности:

  • содержимое защищается быстрым симметричным алгоритмом
  • ключ содержимого защищается асимметрической криптографией
  • допускается множественная адресация (несколько получателей)

Jsrsasign предоставляет высокоуровневую реализацию CMS, скрывающую ASN.1-сложность, но внутренняя структура остаётся полностью соответствующей стандарту.


Базовая структура EnvelopedData

В CMS EnvelopedData всегда представляет собой ASN.1 SEQUENCE со следующими компонентами:

  • version
  • originatorInfo (опционально)
  • recipientInfos
  • encryptedContentInfo
  • unprotectedAttrs (опционально)

В Jsrsasign эта структура отражается через объект CMS, но логически сохраняет ту же иерархию.


Version

Поле version определяет совместимость структуры с версией CMS.

Основные значения:

  • 0 — при использовании KeyTransRecipientInfo без дополнительных атрибутов
  • 2 — при наличии дополнительных типов получателей или расширений

В большинстве практических сценариев Jsrsasign автоматически устанавливает version, исходя из состава recipientInfos.


OriginatorInfo

OriginatorInfo используется редко и содержит дополнительные сертификаты или CRL отправителя.

Структура включает:

  • certs — список сертификатов отправителя
  • crls — список списков отзыва сертификатов

В Jsrsasign данный блок чаще всего отсутствует, поскольку библиотека ориентирована на упрощённые сценарии шифрования сообщений.


RecipientInfos

RecipientInfos — ключевая часть EnvelopedData. Это массив структур, каждая из которых описывает способ защиты симметрического ключа для конкретного получателя.

В Jsrsasign поддерживаются основные типы:

KeyTransRecipientInfo

Наиболее распространённый вариант.

Структура включает:

  • rid (RecipientIdentifier)

    • issuerAndSerialNumber или subjectKeyIdentifier
  • keyEncryptionAlgorithm

  • encryptedKey

Механизм работы:

  1. генерируется случайный симметричный ключ
  2. данные шифруются этим ключом
  3. симметричный ключ шифруется публичным ключом получателя
  4. результат помещается в encryptedKey

KeyAgreeRecipientInfo

Используется в более сложных схемах (ECDH/ DH).

Содержит:

  • originator public key
  • ukm (optional user keying material)
  • key encryption algorithm
  • recipient encrypted keys

В Jsrsasign поддержка ограничена базовыми сценариями, так как основной фокус — RSA-шифрование.


KEKRecipientInfo

Используется при наличии заранее распределённого симметрического ключа (Key Encryption Key).

Структура:

  • KEKIdentifier
  • keyEncryptionAlgorithm
  • encryptedKey

Применяется в корпоративных системах, где используется централизованное управление ключами.


EncryptedContentInfo

Это центральный блок, содержащий зашифрованные данные.

Структура включает:

  • contentType
  • contentEncryptionAlgorithm
  • encryptedContent

contentType

Определяет тип исходных данных:

  • id-data — произвольные данные
  • id-signedData — подписанные структуры
  • id-envelopedData — вложенные CMS структуры

contentEncryptionAlgorithm

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

  • AES-128-CBC
  • AES-256-CBC
  • 3DES-CBC

Jsrsasign обычно использует AES как стандартный вариант.

encryptedContent

Содержит результат симметричного шифрования данных. В CMS он представлен как OCTET STRING, часто с дополнительной ASN.1 обёрткой.


UnprotectedAttrs

Необязательный блок, содержащий атрибуты, не защищённые шифрованием.

Может включать:

  • метаданные сообщения
  • временные метки
  • пользовательские параметры

В Jsrsasign используется редко и обычно игнорируется, поскольку снижает криптографическую строгость структуры.


Внутренняя модель Jsrsasign

В Jsrsasign EnvelopedData представляется через объект CMS, где структура абстрагирована:

  • CMS.EnvelopedData
  • CMS.encrypt
  • CMS.decrypt

При создании структуры библиотека выполняет:

  1. генерацию симметричного ключа
  2. шифрование контента
  3. упаковку ключа для каждого recipient
  4. формирование ASN.1 структуры

При расшифровке выполняется обратный процесс:

  1. извлечение recipientInfo
  2. расшифрование симметричного ключа
  3. расшифрование контента

ASN.1 представление EnvelopedData

Формально структура выглядит следующим образом:

EnvelopedData ::= SEQUENCE {
  version CMSVersion,
  originatorInfo [0] IMPLICIT OriginatorInfo OPTIONAL,
  recipientInfos RecipientInfos,
  encryptedContentInfo EncryptedContentInfo,
  unprotectedAttrs [1] IMPLICIT UnprotectedAttributes OPTIONAL
}

RecipientInfos — SET OF RecipientInfo

EncryptedContentInfo:

EncryptedContentInfo ::= SEQUENCE {
  contentType ContentType,
  contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier,
  encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL
}

Алгоритмическая модель шифрования

Внутренний процесс в Jsrsasign можно разложить на этапы:

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

  • создаётся случайный симметричный ключ K
  • длина зависит от алгоритма (например, 256 бит для AES-256)

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

C = Encrypt_sym(Data, K)

Шифрование ключа для каждого получателя

EK_i = Encrypt_pub(K, PubKey_i)

Формирование структуры

  • recipientInfos ← {EK_1, EK_2, …}
  • encryptedContentInfo ← C

Особенности реализации Jsrsasign

1. Автоматическая работа с ASN.1

Jsrsasign скрывает ASN.1 сериализацию, но внутри используется классическая DER-кодировка.

2. Поддержка RSA как основного механизма

Наиболее стабильный сценарий:

  • RSA-OAEP для защиты ключа
  • AES-CBC для контента

3. Ограниченная поддержка ECC в CMS

Хотя библиотека поддерживает ECDSA и ECDH, CMS EnvelopedData чаще ориентирован на RSA-схемы.

4. Работа с сертификатами X.509

RecipientInfo часто формируется на основе сертификата:

  • извлечение публичного ключа
  • использование issuer + serial number

Многопользовательская модель EnvelopedData

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

Модель:

  • данные шифруются один раз
  • ключ шифруется N раз

Преимущества:

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

Связь EnvelopedData и PKCS#7

EnvelopedData является частью более широкой структуры PKCS#7 / CMS:

  • SignedData
  • EnvelopedData
  • DigestedData
  • EncryptedData

В Jsrsasign эти структуры унифицированы через общий CMS интерфейс, где EnvelopedData является частным случаем защищённого контейнера данных.


Обработка ошибок структуры

При работе с EnvelopedData возможны типовые ошибки:

  • несовпадение ключа получателя
  • повреждение DER структуры
  • неверный алгоритм шифрования
  • отсутствие соответствующего recipientInfo

Jsrsasign в таких случаях возвращает ошибки парсинга ASN.1 или криптографические исключения при расшифровке.


Внутренние зависимости структуры

EnvelopedData тесно связан с:

  • ASN.1 DER encoding
  • CryptoJS (в некоторых сборках)
  • Node.js crypto API (в серверной среде)
  • X.509 certificate parsing

Каждый компонент участвует в формировании конечного CMS контейнера.