CAdES-BES: базовая электронная подпись

CAdES-BES представляет собой профиль расширенных электронных подписей на основе CMS (Cryptographic Message Syntax), определённый в стандартах ETSI, и описывает базовый уровень подписи, в котором гарантируется целостность данных и идентификация подписанта без добавления временных меток, атрибутов долгосрочной валидации или архивных структур.

В экосистеме JavaScript работа с данным форматом реализуется через библиотеку jsrsasign, которая предоставляет низкоуровневые и высокоуровневые средства для формирования CMS/PKCS

Структура профиля CAdES-BES

CAdES-BES (Basic Electronic Signature) базируется на CMS SignedData и включает минимальный набор элементов, необходимых для признания электронной подписи:

  • SignedData структура CMS
  • Подписываемые данные (encapsulated или detached)
  • Сертификат подписанта (X.509)
  • Подпись (signatureValue)
  • Набор подписанных атрибутов (signed attributes)

Ключевым элементом является набор signed attributes, который делает подпись устойчивой к подмене контекста и обеспечивает криптографическую привязку подписи к конкретным данным и сертификату.

В CAdES-BES обязательно присутствуют:

  • content-type (идентификатор типа подписываемого контента)
  • message-digest (хеш исходного сообщения)
  • signing-certificate или signing-certificate-v2 (идентификация сертификата подписанта)

Дополнительно могут присутствовать:

  • signing-time (время подписи, не является доверенной меткой времени)
  • content-hints (описание содержимого)

Криптографическая основа в jsrsasign

Библиотека jsrsasign опирается на объектную модель криптографии, где ключевые сущности представлены классами:

  • KJUR.crypto
  • KJUR.asn1.cms
  • X509
  • KEYUTIL

Генерация CAdES-BES подписи осуществляется через CMS SignedData builder, который формирует ASN.1 структуру, сериализует её в DER и затем кодирует в Base64 или бинарный формат.

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

  • RSA (SHA256withRSA, SHA384withRSA)
  • ECDSA (SHA256withECDSA)
  • SHA-2 семейство хеш-функций

Формирование подписи CMS SignedData

В jsrsasign процесс формирования CAdES-BES подписи строится вокруг объекта CMS SignedData. Базовая структура включает данные, сертификат и приватный ключ подписанта.

Основной процесс можно разложить на этапы:

  1. Подготовка данных
  2. Вычисление хеша
  3. Формирование signed attributes
  4. Подписание DER-структуры
  5. Сборка SignedData

Пример формирования CMS подписи:

const jsrsasign = require("jsrsasign");

const msg = "Data to be signed";

const certPEM = `-----BEGIN CERTIFICATE-----
MIIC...IDAQAB
-----END CERTIFICATE-----`;

const privateKeyPEM = `-----BEGIN PRIVATE KEY-----
MIIE...AB
-----END PRIVATE KEY-----`;

const cmsSigned = new jsrsasign.KJUR.crypto.CMS.CMSSignedData({
    content: { str: msg },
    certs: [certPEM],
    signerInfos: [{
        sid: { cert: certPEM },
        digestAlgorithm: "sha256",
        signatureAlgorithm: "SHA256withRSA",
        signingAttributes: [
            { type: "contentType" },
            { type: "messageDigest" },
            { type: "signingTime" },
            { type: "signingCertificate" }
        ],
        sigKey: privateKeyPEM
    }]
});

const pem = cmsSigned.getPEM();

В данной структуре CMSSignedData выполняет автоматическую генерацию ASN.1 контейнера, включая вычисление хешей и формирование подписанных атрибутов.

Подписанные атрибуты CAdES-BES

Signed attributes являются критическим элементом профиля. Они подписываются вместе с хешем документа, формируя защищённую область данных.

Основные атрибуты:

messageDigest

Содержит хеш исходного сообщения. Вычисляется перед подписью и включается в DER структуру.

contentType

Определяет тип подписываемого контента, обычно id-data для произвольных данных.

signingCertificate / signingCertificateV2

Содержит хеш сертификата подписанта. V2 используется для SHA-256 и выше.

signingTime

Фиксирует локальное время подписи, но не является доверенным временем в юридическом смысле.

jsrsasign автоматически формирует данные атрибуты при использовании CMS API, однако возможно явное управление ими через структуру signerInfos.

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

CAdES-BES в терминах ASN.1 CMS имеет следующую логическую структуру:

  • ContentInfo

    • contentType: signedData

    • content: SignedData

      • version
      • digestAlgorithms
      • encapContentInfo
      • certificates
      • signerInfos

SignerInfo содержит:

  • sid (IssuerAndSerialNumber или SubjectKeyIdentifier)
  • digestAlgorithm
  • signedAttrs
  • signatureAlgorithm
  • signature
  • unsignedAttrs (в CAdES-BES обычно отсутствуют или минимальны)

jsrsasign реализует сериализацию этой структуры через внутренние ASN.1 классы:

  • KJUR.asn1.cms.SignedData
  • KJUR.asn1.cms.SignerInfo
  • KJUR.asn1.DER*

Работа с сертификатами X.509

CAdES-BES требует включения сертификата подписанта в контейнер SignedData. jsrsasign предоставляет инструменты для работы с PEM/DER сертификатами:

const x509 = new jsrsasign.X509();
x509.readCertPEM(certPEM);

const serial = x509.getSerialNumberHex();
const issuer = x509.getIssuerString();

Сертификат используется для:

  • формирования sid (идентификатор подписанта)
  • вычисления signingCertificate атрибута
  • включения в CMS контейнер

Проверка подписи CAdES-BES

Проверка выполняется через CMS SignedData parser:

const cms = new jsrsasign.KJUR.crypto.CMS.CMSSignedData({
    pem: cmsSignedPEM
});

const result = cms.verify();

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

  • извлечение SignedData
  • восстановление messageDigest
  • проверку signed attributes
  • криптографическую верификацию подписи с использованием публичного ключа
  • сопоставление сертификата подписанта

Ключевым моментом является проверка signed attributes, поскольку именно они защищают структуру от изменения контекста подписи.

Detached и attached подписи

CAdES-BES может использовать два режима:

Attached signature

Данные включаются внутрь CMS структуры (encapsulated content). В jsrsasign это выражается через content.str.

Detached signature

Данные не включаются в CMS, а передаются отдельно. В этом случае:

  • content отсутствует в CMS
  • messageDigest вычисляется отдельно
  • проверка требует внешнего источника данных

Пример detached режима:

const cms = new jsrsasign.KJUR.crypto.CMS.CMSSignedData({
    content: { str: "" },
    detached: true,
    certs: [certPEM],
    signerInfos: [{
        sid: { cert: certPEM },
        sigKey: privateKeyPEM
    }]
});

Алгоритмы хеширования и подписи

CAdES-BES требует согласованности алгоритмов между хешированием и подписью. jsrsasign поддерживает:

  • SHA-1 (устаревший)
  • SHA-256 (стандартный)
  • SHA-384
  • SHA-512

Подпись формируется через PKCS#1 v1.5 или ECDSA:

  • SHA256withRSA
  • SHA384withRSA
  • SHA256withECDSA

Выбор алгоритма влияет на формирование signingCertificateV2 и структуру DigestInfo.

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

Реализация CAdES-BES в jsrsasign ориентирована на совместимость с PKCS#7/CMS, а не на полный стек ETSI расширений. Это означает:

  • поддержка базового BES профиля присутствует
  • отсутствует полноценная LTV-валидация
  • временные метки TSA не интегрированы в базовую CMS сборку
  • структура расширений ограничена CMS SignedAttributes

Внутренняя модель строится на:

  • KJUR.crypto.CMS builder
  • ASN.1 сериализации через DER
  • PEM/HEX конвертациях

Формирование signingCertificateV2

При использовании SHA-256 и выше применяется структура ESSCertIDv2:

  • hashAlgorithm
  • certHash
  • issuerSerial

jsrsasign автоматически формирует этот атрибут при наличии сертификата и корректного алгоритма подписи.

Типовые ошибки формирования

В процессе генерации CAdES-BES часто возникают структурные несоответствия:

  • отсутствие messageDigest в signed attributes
  • несоответствие алгоритма подписи и хеша
  • некорректный DER порядок атрибутов
  • использование неподписанных данных вместо signed attributes
  • несовпадение сертификата в sid и signingCertificate

CMS SignedData требует строгого соблюдения ASN.1 порядка, иначе верификация будет невозможна.

Внутренняя сериализация ASN.1 в jsrsasign

jsrsasign использует иерархию объектов DER:

  • DERSequence
  • DERSet
  • DERInteger
  • DERObjectIdentifier
  • DEROctetString

Signed attributes кодируются как SET OF Attribute, где каждый атрибут представляет:

  • OID
  • SET OF values

Подпись вычисляется не по сырому документу, а по DER-encoded signedAttrs, что критически важно для корректной реализации CAdES-BES.

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

CAdES-BES, сформированный через jsrsasign, совместим с системами, поддерживающими:

  • PKCS#7/CMS (RFC 5652)
  • ETSI CAdES baseline profiles
  • Java BouncyCastle CMS
  • OpenSSL CMS verify

Совместимость определяется корректностью ASN.1 структуры и соответствием signed attributes стандарту ETSI.

Роль CMS в экосистеме CAdES

CMS является базовым контейнером, на котором строится весь стек CAdES:

  • CMS SignedData → CAdES-BES
  • CMS + timestamp → CAdES-T
  • CMS + revocation data → CAdES-C
  • CMS + archive → CAdES-A

jsrsasign реализует первую ступень этой иерархии, обеспечивая фундамент для построения более сложных профилей поверх SignedData структуры