ASN.1, DER и OID: чтение внутреннего формата CMS¶
Зачем специалисту знать ASN.1¶
CMS — не произвольный поток зашифрованных байтов. Он содержит вложенные структуры ASN.1: SEQUENCE, SET, INTEGER, OCTET STRING, OBJECT IDENTIFIER. В ASN.1 определены типы полей, а DER/BER описывают правила записи значений в байты. По этим правилам можно последовательно разобрать сообщения, сертификаты и записи алгоритмов.
Самый важный для совместимости тип — OBJECT IDENTIFIER (OID). Это числовой путь в пространстве имен, например 1.2.643.2.2.21, обозначающий ГОСТ 28147-89 в старом CMS-профиле. OID не содержит сам криптографический алгоритм: он только позволяет программе выбрать заранее реализованный код и корректно прочитать параметры.
Примеры OID из рассматриваемых документов¶
| OID | Назначение | Источник |
|---|---|---|
1.2.643.2.2.9 |
ГОСТ Р 34.11-94 | RFC 4490 §2 |
1.2.643.2.2.10 |
HMAC по ГОСТ Р 34.11-94 | RFC 4490 §6 |
1.2.643.2.2.21 |
ГОСТ 28147-89 | RFC 4490 §5 |
1.2.643.7.1.1.2.2 |
ГОСТ Р 34.11-2012/256 | Проект ТК26 §4 |
1.2.643.7.1.1.2.3 |
ГОСТ Р 34.11-2012/512 | Проект ТК26 §4 |
1.2.643.7.1.1.4.1 |
HMAC Стрибог-256 | Проект ТК26 §8 |
1.2.643.7.1.1.4.2 |
HMAC Стрибог-512 | Проект ТК26 §8 |
Наличие знакомого OID внутри DER не гарантирует, что приложение знает также нужные параметры и режим. Кроме того, поле алгоритма должно интерпретироваться в контексте структуры: один OID в SignerInfo и другой в EncryptedContentInfo отвечают за разные операции.
Три вида кодировки, которые часто путают¶
DER — бинарное представление ASN.1 с однозначными правилами кодирования. Многие файлы .p7s/.p7m хранятся именно так.
PEM — текстовая броня Base64 с границами BEGIN … и END …; внутри может находиться DER-представление определённого ASN.1-объекта. Сам по себе PEM не говорит, что внутри подпись ГОСТ.
S/MIME — формат MIME-сообщения с заголовками, типами содержимого и, в зависимости от режима, вложенным CMS. Почтовый файл .eml нельзя без проверки подавать в программу, ожидающую чистый бинарный DER.
Как прочитать реальный контейнер¶
Для файла document.p7s, полученного из доверенного источника, сначала проверьте внешний тип формата и структуру:
openssl asn1parse показывает низкоуровневые поля. Для полноценной расшифровки смысла структуры используйте CMS-декодер:
Это команды просмотра, а не проверки криптографической подписи и не решения вопроса доверия сертификату. В openssl cms -verify должны быть заданы правильные сертификаты, доверенная цепочка и, при необходимости, исходный документ для detached-подписи. Подробный процесс: OpenSSL CMS.
Почему нельзя просто искать байты с OID¶
У ASN.1 есть длины, вложенные контейнеры и контекстные теги. Совпадение последовательности байтов внутри зашифрованного содержимого или неподходящего вложенного объекта не доказывает, что именно этот алгоритм использован для подписи. Нужно разбирать дерево ASN.1 и определять OID в соответствующем поле: например, SignerInfo.signatureAlgorithm либо EncryptedContentInfo.contentEncryptionAlgorithm.
Дополнительно BER и DER отличаются по правилам допустимого представления. Если программа повторно кодирует подписанные атрибуты неканонично, байты проверяемой подписи могут измениться. Для SignedData особенно важны правила DER-кодирования signedAttrs в RFC 5652.
Практический пример для чтения шестнадцатеричных данных¶
В проекте ТК26, раздел 9, приведён DER-фрагмент SMIMECapability для Стрибог-256:
Первый байт 30 обозначает SEQUENCE, 0A — длину вложенного содержимого, 06 — тип OBJECT IDENTIFIER, 08 — длину значения OID. Это удобный короткий пример того, что ASN.1 состоит из тегов и длин, а не из текстовых названий алгоритмов. Следующий шаг — декодировать байты OID и сопоставить их с таблицей спецификации.
TLV и каноничность: что видит декодер¶
В BER/DER объект записывается как тег → длина → значение (TLV). ASN.1 определяет структуру и типы, BER допускает некоторые альтернативные кодировки, а DER устанавливает более строгие правила однозначного представления. Это важно прежде всего для подписанных атрибутов CMS: при разной сериализации одной логической структуры меняются подписанные байты.
30 0A SEQUENCE, длина 10
06 08 OBJECT IDENTIFIER, длина 8
2A 85 03 07 01 01 01 01 закодированные дуги OID
Указанный набор байт — образец чтения TLV, а не готовое доказательство назначения OID в любом сообщении. Имя алгоритма определяется его положением в конкретном ASN.1-типе и соответствующей спецификацией.
Почему у одного алгоритма несколько OID¶
Разные идентификаторы могут относиться к хэш-функции, алгоритму подписи с хэшем, типу открытого ключа, параметрам эллиптической кривой, режиму шифрования или алгоритму переноса ключа. Это разные объекты! Чтение 1.2.643... без понимания поля — только первый шаг. Сверяйте терминологию с RFC 9215 (X.509), RFC 4490 (исторический CMS) и каталогом OID НАЙС.ОС.
Порядок байтов, битов и компонентов подписи¶
У ГОСТ-криптографии ошибки совместимости часто происходят не на уровне вычисления эллиптических операций, а при упаковке в ASN.1: байтовый порядок координат открытого ключа, порядок компонентов r/s, фиксированная длина и кодировка параметров. Нельзя выводить из одного профиля X.509 формат CMS или формат прикладного API. Для X.509 см. RFC 9215 §4, для прикладной интеграции — форматы подписей.
Методика исследования без «магических» подмен¶
# Пример для локального файла; только просмотр, без записи результата.
file document.p7s
openssl asn1parse -inform DER -in document.p7s -i | head -n 100
openssl cms -cmsout -print -inform DER -in document.p7s -noout
Третья команда декодирует смысл CMS-полей, но не подтверждает подпись. Если файл PEM или содержит MIME-заголовки, нужно выбрать соответствующий входной формат, а не считать сообщение испорченным. Обратите внимание, что asn1parse может показывать BER-содержимое; задача криптографической проверки signedAttrs — применять требования DER, а не переписывать весь контейнер.
Что фиксировать в протоколе испытаний¶
| Поле протокола | Что записывать |
|---|---|
| Тип внешнего контейнера | ContentInfo.contentType, файл/URI |
| Подпись | SignerInfo.digestAlgorithm, signatureAlgorithm, sid |
| Сертификат | алгоритм subjectPublicKeyInfo, кривая, serial, issuer |
| Шифрование | EncryptedContentInfo.contentEncryptionAlgorithm, параметры |
| Получатель | вид RecipientInfo, управление CEK, UKM |
| Представление | DER/BER/PEM/MIME, байтовые длины |
| Проверка | parse / crypto / chain / revocation / policy |
Проверенные практические сценарии: OpenSSL CMS, диагностика контейнера, GPGSM, план межоперабельности.
Источники¶
- RFC 5652: структуры CMS.
- RFC 4490: OID старого ГОСТ, разделы 2–7 и ASN.1-модули.
- Проект ТК26: разделы 4–9, примеры в приложении В.
- RFC 9215: ГОСТ 2012 в X.509 и корректные представления ключей.
Маршрут чтения: Контейнеры CMS → Матрица совместимости → Диагностика