ContentInfo в CMS (Cryptographic Message Syntax) представляет собой контейнер верхнего уровня, который определяет формат криптографически защищённых сообщений. В библиотеке Jsrsasign он используется как основа для построения и разбора структур PKCS
ContentInfo всегда состоит из двух ключевых компонентов:
В ASN.1 это выглядит следующим образом:
ContentInfo ::= SEQUENCE {
contentType ContentType,
content [0] EXPLICIT ANY DEFINED BY contentType
}
Тип data является самым простым вариантом ContentInfo. Он представляет собой «сырые» данные без криптографической защиты.
OID для data:
1.2.840.113549.1.7.1
Этот тип используется, когда сообщение инкапсулируется в CMS, но не подписывается и не шифруется.
Структура content в этом случае содержит OCTET STRING с исходными данными.
const cms = new KJUR.asn1.cms.ContentInfo({
type: "data",
content: "616263" // hex для "abc"
});
const pem = cms.getPEM();
Внутри Jsrsasign данные кодируются как OCTET STRING и помещаются в структуру ContentInfo без дополнительных атрибутов.
signedData — один из наиболее сложных и часто используемых типов CMS. Он реализует цифровую подпись с возможностью включения или исключения оригинального сообщения.
OID:
1.2.840.113549.1.7.2
SignedData включает:
Основная идея заключается в том, что данные могут быть либо:
Содержит:
Содержит информацию о подписи:
const sd = new KJUR.asn1.cms.SignedData({
content: {
type: "data",
data: "616263"
},
signerInfos: [{
version: 1,
sid: { type: "issdn", cert: certObj },
hashAlg: "sha256",
signAlg: "RSA",
signature: "..."
}],
certs: [certObj]
});
const cms = new KJUR.asn1.cms.ContentInfo({
type: "signedData",
content: sd
});
envelopedData используется для шифрования данных. Он реализует гибридную криптосистему: данные шифруются симметричным алгоритмом, а ключ — асимметричным.
OID:
1.2.840.113549.1.7.3
Основные компоненты:
Содержит:
Каждый получатель имеет свою запись:
const ed = new KJUR.asn1.cms.EnvelopedData({
content: {
type: "data",
data: "616263"
},
recipients: [{
cert: certObj,
alg: "RSA"
}],
symAlg: "aes256"
});
const cms = new KJUR.asn1.cms.ContentInfo({
type: "envelopedData",
content: ed
});
digestedData используется для хранения данных вместе с их хэш-значением. В отличие от signedData, он не содержит криптографической подписи, а только контрольную сумму.
OID:
1.2.840.113549.1.7.5
Состоит из:
Аналогично signedData:
Хэш значения содержимого, вычисленный по указанному алгоритму (SHA-1, SHA-256 и др.)
const dd = new KJUR.asn1.cms.DigestedData({
content: {
type: "data",
data: "616263"
},
hashAlg: "sha256"
});
const cms = new KJUR.asn1.cms.ContentInfo({
type: "digestedData",
content: dd
});
В Jsrsasign CMS реализован через набор ASN.1 классов:
Каждый класс отвечает за формирование соответствующей ASN.1 структуры и кодирование её в DER/PEM формат.
Общий принцип построения:
const ci = KJUR.asn1.cms.ContentInfo.fromPEM(pemString);
if (ci.contentType === "signedData") {
const sd = ci.content;
}
Каждый тип ContentInfo строго идентифицируется OID:
Jsrsasign использует эти OID для автоматического выбора парсера и интерпретации структуры.
ContentInfo может содержать только один тип данных, однако на практике структуры часто комбинируются:
Такая вложенность позволяет строить сложные криптографические протоколы поверх CMS, сохраняя совместимость с PKCS#7 и RFC 5652.