Несколько основных подписантов CMS

HotPDF может создать один контейнер SignedData по RFC 5652, содержащий до 256 независимых основных записей SignerInfo

Запросы на сборку

Каждый THPDFCMSPrimarySignerRequest приносит собственный сертификат и key material, document digest, THPDFCMSSignOptions, опциональный THPDFSignatureProvider и идентификатор ключа провайдера

HPDFCMSBuildMultiSignedData валидирует каждый запрос до вызова любого нативного ключа, внешнего callback, timestamp callback, PDF MAC callback или провайдера, не давая невалидному позднему запросу вызвать лишнюю частичную удалённую подпись

SetLength(Signers, 2);
Signers[0].KeyMaterial := FirstKey;
Signers[0].DocumentDigest := HPDFCMSDigestBytes(DocumentBytes, cmsdaSHA256);
Signers[0].Options := FirstOptions;

Signers[1].KeyMaterial := SecondKey;
Signers[1].DocumentDigest := HPDFCMSDigestBytes(DocumentBytes, cmsdaSHA384);
Signers[1].Options := SecondOptions;
Signers[1].Provider := RemoteProvider;
Signers[1].KeyIdentifier := 'approval-key';

CMS := HPDFCMSBuildMultiSignedData(Signers);

Детерминированное слияние

HPDFCMSMergeSignedData объединяет уже собранные CMS-контейнеры для асинхронных или распределённых сценариев подписи без повторения операций с приватным ключом

Каждый входной контейнер должен использовать конверты и множества signedData определённой длины, должен объявлять каждый digest-алгоритм, используемый его основными подписантами, и должен нести байт-в-байт идентичный encapContentInfo; дополнительные объявленные digest-алгоритмы остаются допустимы

Слитый контейнер дедуплицирует digest-алгоритмы, сертификаты и значения отзывов, сортирует все значения SET OF по порядку байтов DER, сохраняет каждого основного подписанта и поднимает внешнюю версию до наибольшего требования среди валидных входов

Порядок запросов после кодирования намеренно не наблюдаем, поскольку signerInfos — это DER SET OF; поэтому результаты разбора и верификации используют порядок DER, а не порядок запросов

Сборка с одним подписантом и слияние одного контейнера сохраняют существующие байты CMS в точности

Независимая валидация

HPDFParseCMSSignatures, HPDFVerifyCMSSignaturesEx и HPDFVerifyCMSSignerReport возвращают независимый результат по каждому основному подписанту, включая его атрибуты, политику digest и подписи, подходящий сертификат, timestamp, контрподписи и статус отказа

Битый или криптографически невалидный подписант не стирает валидный результат соседа, при этом агрегированный Boolean-результат равен false, если хотя бы один основной подписант не прошёл

Размер placeholder

HPDFCMSEstimateMultiSignerPlaceholder вычисляет длину каждой подписи без подписывания, строит точную дедуплицированную статическую форму контейнера с синтетическими значениями подписей, суммирует резервы динамических callback и один раз применяет настроенные глобальные safety margin, выравнивание, минимум и максимум

THPDFCMSPlaceholderEstimateInfo.SignatureBytes сообщает сумму по всем основным подписантам, а cpesMixed помечает результат, где подписанты использовали разные источники оценки

Граница PDF-сценариев

Multi-signer API открывают универсальную функциональность CMS для приложений, чей потребляющий профиль допускает несколько основных подписантов в одном контейнере

Многие PDF- и PAdES-сценарии подписи закладывают одного основного подписанта на словарь подписи, поэтому используйте отдельные поля PDF-подписей, если профиль получателя явно не принимает multi-signer CMS

См. подписантов CMS SubjectKeyIdentifier, согласованность digest-алгоритмов CMS и автоподбор размера CMS placeholder