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, и это не противоречие.
Несколько уровней проверки¶
- Формат. Приложение способно декодировать ContentInfo и вложенные объекты.
- Алгоритм. Приложение узнаёт OID и поддерживает нужные параметры.
- Криптография. Подпись или MAC математически корректны; шифрование можно раскрыть.
- Доверие. Сертификат строит допустимую цепочку доверия, соответствует назначению и не считается отозванным по правилам политики проверки.
- Юридический контекст. Для регулируемого документооборота дополнительно применяются требования к сертификату, подписи, времени и средству подписи; одного
Verify OKнедостаточно.
Пример: сертификат включён в SignedData, но подписан неизвестным центром. Криптографическая проверка может пройти, а проверка доверия — нет. Это не ошибка алгоритма ГОСТ.
Источники и продолжение¶
- RFC 5652, разделы 3–9 — синтаксис CMS.
- RFC 4490, введение и разделы 2–7 — старый профиль ГОСТ.
- Проект ТК26 2014 года, разделы 1 и 3 — форматы и термины.
Модель объектов 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¶
- Ограничить размер файла, глубину ASN.1 и количество вложенных объектов; работа с чужими CMS — обработка недоверенного ввода.
- До проверки подписи не считать вложенные имена, MIME-заголовки или атрибуты доказательством происхождения документа.
- Отдельно логировать
parse,crypto,trust,policyиinterop-ошибки: это принципиально разные причины отказа. - Для AEAD не выдавать приложению расшифрованные байты до успешной проверки тега;
EnvelopedDataс традиционным режимом шифрования не следует автоматически считать AEAD. - Проверять не только криптографическую библиотеку, но и прикладную политику допуска алгоритмов и сертификатов.
Подробнее о формате полей см. ASN.1, DER и OID; о подтверждении личности подписанта — политика доверия; о выполнении операций в НАЙС.ОС — OpenSSL CMS и libksba.
Маршрут чтения: Обзор → SignedData → EnvelopedData