Перейти к содержанию

CMS: язык криптографических сообщений

Зачем нужен формат поверх криптографии

Подписать хэш документа недостаточно, если получателю неизвестно, какой сертификат использован и какие именно байты были подписаны. Зашифровать файл тоже недостаточно: получатель должен знать алгоритм, параметры и способ получения ключа. CMS решает задачу представления этих сведений в одном структурированном сообщении.

По RFC 5652 CMS основан на ASN.1. На внешнем уровне используется ContentInfo, включающий идентификатор типа содержимого contentType и само содержимое content. Поэтому два файла с одинаковым расширением .p7m могут содержать совершенно разные криптографические конструкции.

CMS ContentInfo
├── contentType (OID)
└── content (тип определяется contentType)
    ├── SignedData          подпись
    ├── EnvelopedData       шифрование для получателей
    ├── DigestedData        контрольный хэш
    ├── AuthenticatedData   код аутентификации MAC
    ├── EncryptedData       шифрование с заранее известным ключом
    └── Data                обычные данные

Это схема, не точное ASN.1-описание всех допустимых вариантов CMS. Полные структуры находятся в RFC 5652.

Подпись не равна шифрованию

SignedData предназначена для подписи: получатель может проверить целостность подписанных байтов и связь подписи с публичным ключом. Содержимое при этом обычно остаётся читаемым. EnvelopedData предназначена для конфиденциальности: содержимое зашифровано одноразовым симметричным ключом, а у получателей есть собственные механизмы получения этого ключа. Само по себе шифрование не утверждает личность отправителя.

AuthenticatedData использует MAC и общий секретный ключ. Это проверка целостности и владения ключом; она не эквивалентна цифровой подписи, которую можно проверять по открытому ключу. DigestedData вообще не обеспечивает защиту от злонамеренной подмены: обычный хэш не секретен и может быть пересчитан вместе с заменённым документом.

Цель CMS-тип Что требуется проверить
Электронная подпись SignedData Подпись, подписанные атрибуты, сертификат, доверие
Шифрование для адресата EnvelopedData Возможность извлечь CEK и расшифровать содержимое
Контрольная сумма DigestedData Совпадение хэша, без вывода о подлинности
Симметричная аутентификация AuthenticatedData MAC и доступность правильного ключа
Шифрование общим ключом EncryptedData Алгоритм, параметры и общий секрет

Присоединённая и отсоединённая подпись

Подписываемое содержимое может находиться внутри CMS или предоставляться отдельно. В первом случае получателю достаточно контейнера; во втором — нужны контейнер и точно те же исходные байты, которые были использованы при создании подписи.

Например, файл contract.pdf может сопровождаться contract.pdf.sig. Текстовый редактор не обязан менять смысл PDF, но изменение хотя бы одного байта меняет хэш; документ перестаёт соответствовать подписи. Также не следует автоматически считать, что любое расширение .sig означает CMS: оно может обозначать подпись другого стандарта.

Сравнивать нужно по реальному типу содержимого и правилам профиля обмена, а не по суффиксу имени файла.

Где находятся сведения об алгоритмах

В CMS применяется структура AlgorithmIdentifier, которая обычно содержит OID алгоритма и предусмотренные его профилем параметры. Сам по себе OID отвечает на вопрос «что за операция», а связанные параметры могут уточнять кривую, набор подстановок, IV или правила обработки ключей.

Это принципиально для ГОСТ: разные наборы параметров одного семейства алгоритмов не всегда дают совместимые результаты. Подпись и шифрование могут использовать разную криптографию внутри одного CMS, и это не противоречие.

Несколько уровней проверки

  1. Формат. Приложение способно декодировать ContentInfo и вложенные объекты.
  2. Алгоритм. Приложение узнаёт OID и поддерживает нужные параметры.
  3. Криптография. Подпись или MAC математически корректны; шифрование можно раскрыть.
  4. Доверие. Сертификат строит допустимую цепочку доверия, соответствует назначению и не считается отозванным по правилам политики проверки.
  5. Юридический контекст. Для регулируемого документооборота дополнительно применяются требования к сертификату, подписи, времени и средству подписи; одного Verify OK недостаточно.

Пример: сертификат включён в SignedData, но подписан неизвестным центром. Криптографическая проверка может пройти, а проверка доверия — нет. Это не ошибка алгоритма ГОСТ.

Источники и продолжение

Модель объектов CMS: тип, содержимое, вложенность

ContentInfo — внешний объект, а не синоним SignedData. По RFC 5652 §3 он связывает contentType (OID) с конкретным ASN.1-содержимым. Один CMS-контейнер может содержать другой; это особенно важно при совмещении подписи и шифрования.

Тип CMS Что хранит Основная гарантия Чего не гарантирует
data Произвольные байты Не задаёт защиты Подписи, конфиденциальности
signedData Данные и сведения о подписантах Криптографическая проверка подписи при правильной обработке Доверия к подписанту без PKI
envelopedData Зашифрованное содержимое и ключи для получателей Конфиденциальность в пределах выбранного криптографического профиля Автоматическую проверку авторства
digestedData Данные и хэш Контроль совпадения публичного хэша Защиту от злонамеренной подмены
encryptedData Зашифрованное содержимое с внешним управлением ключом Конфиденциальность Способ доставки ключа получателям
authenticatedData Данные и MAC Подлинность для обладателей общего секрета Публично проверяемую подпись
authEnvelopedData AEAD-содержимое и управление ключами Защиту шифротекста + связанных данных при корректном AEAD-профиле Поддержку любого AEAD любой библиотекой

Последний тип определён дополнительно в RFC 5083 и не является одним из шести исходных типов RFC 5652. Это существенно, когда внешняя система сообщает о «поддержке CMS», но реализует только SignedData и EnvelopedData.

Подписать, затем зашифровать — или наоборот?

A. sign → encrypt
   исходные байты → SignedData → EnvelopedData → получатель расшифровывает → проверяет подпись

B. encrypt → sign
   исходные байты → EnvelopedData → SignedData → проверка внешней подписи → расшифрование

C. sign → encrypt → sign (тройная обёртка)
   SignedData → EnvelopedData → SignedData

Три композиции не взаимозаменяемы: во внешнем варианте подписывается шифротекст, а не обязательно исходный открытый документ. Тройная обёртка описана в RFC 2634, но конкретное приложение должно поддерживать соответствующий профиль. В проекте электронного документооборота порядок вложений нужно фиксировать в техническом задании, а не определять по расширению .p7m.

Attached и detached: что именно необходимо сохранить

Attached (encapsulated): encapContentInfo.eContent содержит байты документа. Detached: это поле отсутствует, а документ передаётся отдельно. В последнем случае проверка должна получить в точности те байты, которые были подписаны, включая особенности строк, кодировок и возможной каноникализации MIME. Контент не следует «чинить» перекодированием до завершения проверки.

Detached:
 ├── report.pdf              ← подписанные байты
 └── report.pdf.p7s          ← SignedData без вложенного eContent

Attached:
 └── report.p7m              ← структура + вложенное содержимое

Имена файлов — лишь соглашение приложения: встречаются .sig, .sgn, .p7s, .p7m, .cms и .eml, и они не позволяют однозначно установить тип без разбора ASN.1/MIME.

Инварианты при обработке недоверенного CMS

  1. Ограничить размер файла, глубину ASN.1 и количество вложенных объектов; работа с чужими CMS — обработка недоверенного ввода.
  2. До проверки подписи не считать вложенные имена, MIME-заголовки или атрибуты доказательством происхождения документа.
  3. Отдельно логировать parse, crypto, trust, policy и interop-ошибки: это принципиально разные причины отказа.
  4. Для AEAD не выдавать приложению расшифрованные байты до успешной проверки тега; EnvelopedData с традиционным режимом шифрования не следует автоматически считать AEAD.
  5. Проверять не только криптографическую библиотеку, но и прикладную политику допуска алгоритмов и сертификатов.

Подробнее о формате полей см. ASN.1, DER и OID; о подтверждении личности подписанта — политика доверия; о выполнении операций в НАЙС.ОС — OpenSSL CMS и libksba.


Маршрут чтения: Обзор → SignedData → EnvelopedData