Модуль asn1cms

ASN.1 CMS в Jsrsasign реализует работу с Cryptographic Message Syntax (CMS, ранее PKCS

CMS строится вокруг структуры ContentInfo, внутри которой хранится конкретный тип данных: SignedData, EnvelopedData, DigestedData или EncryptedData. В контексте Jsrsasign основной интерес сосредоточен на SignedData и базовой инфраструктуре ASN.1 кодирования.


Структура ContentInfo

CMS всегда начинается с обёртки ContentInfo:

  • contentType — идентификатор типа содержимого (OID)
  • content — непосредственно ASN.1 структура выбранного типа

В Jsrsasign это представляется через объекты, создаваемые в пространстве KJUR.asn1.cms.

Пример логической структуры:

ContentInfo ::= SEQUENCE {
  contentType OBJECT IDENTIFIER,
  content [0] EXPLICIT ANY DEFINED BY contentType
}

SignedData как основная модель подписи

SignedData — ключевая структура CMS, используемая для цифровых подписей.

Она включает:

  • версию структуры
  • набор алгоритмов подписи
  • данные (encapContentInfo)
  • сертификаты
  • CRL (опционально)
  • подписи (SignerInfo)

Jsrsasign формирует эту структуру через высокоуровневые функции, скрывающие ручную работу с ASN.1 узлами.


EncapsulatedContentInfo

Данные, которые подписываются, помещаются в EncapsulatedContentInfo:

  • eContentType — OID типа содержимого (например, data)
  • eContent — бинарные данные или отсутствующее поле (detached signature)

В Jsrsasign возможно формировать как встроенную (attached), так и отделённую подпись.


Формирование SignedData в Jsrsasign

Библиотека предоставляет API уровня CMS builder, который упрощает создание структуры:

const cms = new KJUR.asn1.cms.SignedData({
  content: "616263", // hex строки "abc"
  certs: [certPEM],
  signerPrvKey: prvKeyPEM,
  signerCert: certPEM,
  hashAlg: "sha256"
});

const cmsData = cms.getContentInfo();

Внутри происходит:

  • вычисление хэша
  • формирование SignerInfo
  • упаковка сертификатов
  • кодирование ASN.1 DER

SignerInfo и криптографическая подпись

SignerInfo содержит информацию о подписи конкретного участника:

  • issuerAndSerialNumber
  • digestAlgorithm
  • signatureAlgorithm
  • signatureValue
  • signedAttributes (опционально)

Jsrsasign автоматически формирует signedAttributes, включая:

  • messageDigest
  • contentType
  • signingTime

Это соответствует CMS Advanced Electronic Signature (CAdES) базовому уровню.


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

Упрощённая ASN.1 модель:

SignerInfo ::= SEQUENCE {
  version INTEGER,
  sid SignerIdentifier,
  digestAlgorithm AlgorithmIdentifier,
  signedAttrs [0] IMPLICIT SET OPTIONAL,
  signatureAlgorithm AlgorithmIdentifier,
  signature OCTET STRING,
  unsignedAttrs [1] IMPLICIT SET OPTIONAL
}

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


Проверка CMS подписи

Проверка выполняется через парсинг ContentInfo и извлечение SignedData:

const cms = new KJUR.asn1.cms.SignedData({ cmsContent: cmsBase64 });

const result = cms.verify();

Процесс включает:

  • декодирование ASN.1 структуры
  • извлечение SignerInfo
  • проверку сертификата
  • пересчёт messageDigest
  • проверку подписи через публичный ключ

Работа с сертификатами внутри CMS

CMS может содержать цепочку сертификатов:

  • end-entity certificate
  • intermediate CA
  • root CA (иногда опционально)

Jsrsasign помещает их в поле certificates как SET OF Certificate.

При проверке выполняется:

  • построение цепочки доверия
  • сопоставление issuer/serial
  • проверка подписи сертификатов

Detached и attached подписи

CMS SignedData поддерживает два режима:

Attached signature

Данные включены внутрь CMS:

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

Detached signature

Данные не включены:

  • подписывается только hash
  • данные передаются отдельно

Jsrsasign позволяет управлять этим через параметры content / detached mode.


EnvelopedData и CMS шифрование

Хотя основное использование asn1cms связано с подписями, CMS также поддерживает шифрование через EnvelopedData:

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

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

  • RecipientInfo
  • EncryptedContentInfo
  • EncryptedContent

ASN.1 кодирование в Jsrsasign

Вся CMS-структура строится на ASN.1 DER encoder:

  • KJUR.asn1.DERSequence
  • KJUR.asn1.DERSet
  • KJUR.asn1.DEROctetString
  • KJUR.asn1.DERObjectIdentifier

CMS модуль является надстройкой над этими базовыми примитивами.


Алгоритмы подписи

Поддерживаемые алгоритмы:

  • SHA-1 (legacy)
  • SHA-256
  • SHA-384
  • SHA-512
  • RSA
  • ECDSA

Комбинации:

  • sha256WithRSAEncryption
  • ecdsa-with-SHA256

Выбор алгоритма влияет на digestAlgorithm и signatureAlgorithm внутри SignerInfo.


Обработка ошибок при разборе CMS

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

  • некорректный DER формат
  • несоответствие OID contentType
  • повреждённая подпись
  • отсутствующие сертификаты

Jsrsasign возвращает структурированные ошибки при парсинге ASN.1 узлов.


Взаимодействие с PEM и DER

CMS модуль работает как с:

  • PEM (Base64 + header/footer)
  • DER (binary / hex)

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

  • X509.pemToHex
  • KJUR.asn1.ASN1Util.hexToPem

Внутренние OID CMS

Основные OID, используемые в CMS:

  • 1.2.840.113549.1.7.1 — data
  • 1.2.840.113549.1.7.2 — signedData
  • 1.2.840.113549.1.7.3 — envelopedData
  • 1.2.840.113549.1.9.4 — messageDigest
  • 1.2.840.113549.1.9.3 — contentType

Jsrsasign использует их для маршрутизации парсинга ContentInfo.


SignedAttributes и их роль

SignedAttributes критически важны для защиты структуры подписи:

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

В Jsrsasign они сериализуются как DER SET и включаются в вычисление подписи.


Взаимодействие CMS с внешними системами

CMS структуры Jsrsasign совместимы с:

  • OpenSSL CMS
  • Java BouncyCastle CMS
  • .NET System.Security.Cryptography.Pkcs

Основное требование — корректный DER и совпадение алгоритмов.


Разбор CMS через Jsrsasign парсер

Пример декодирования:

const cms = new KJUR.asn1.cms.SignedData({
  cmshex: cmsHex
});

const signerInfos = cms.getSignerInfos();
const certs = cms.getCertificates();
const content = cms.getContent();

Парсер выполняет рекурсивный разбор ASN.1 дерева.


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

  • полностью JavaScript реализация без нативных зависимостей
  • строгая работа с DER (без BER-поблажек)
  • ориентация на криптографическую совместимость
  • глубокая интеграция с X.509 модулем библиотеки

Ограничения формата CMS в Jsrsasign

  • нет поддержки всех расширений CAdES уровня LTV
  • ограниченная работа с OCSP/CRL в автоматическом режиме
  • отсутствие полноценного S/MIME pipeline

Использование CMS как контейнера данных

CMS часто используется как:

  • контейнер подписанных документов
  • формат обмена юридически значимыми сообщениями
  • структура для защищённого API обмена

Jsrsasign обеспечивает генерацию такой структуры без необходимости ASN.1 ручного кодирования.