CMS 多主签名者
HotPDF 可以创建一个 RFC 5652 SignedData 容器,其中最多包含 256 条彼此独立的主 SignerInfo 记录
构建请求
每个 THPDFCMSPrimarySignerRequest 自带证书与密钥材料、文档摘要、THPDFCMSSignOptions、可选的 THPDFSignatureProvider 以及 provider 密钥标识符
HPDFCMSBuildMultiSignedData 会先校验所有请求,再去调用任何本机密钥、外部 callback、时间戳 callback、PDF MAC callback 或 provider,避免后面的无效请求造成本可避免的部分远程签名开销
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 容器,适配异步或分布式签名工作流,无需重复私钥运算
每个输入必须使用定长(definite-length)signedData 信封和集合,必须声明其主签名者用到的所有摘要算法,并且必须携带逐字节相同的 encapContentInfo;额外声明的摘要算法依然允许
合并后的容器会对摘要算法、证书和吊销值去重,按 DER 字节序对所有 SET OF 值排序,保留每一个主签名者,并把外层版本号提升到所有输入中的最高有效要求
编码之后请求顺序刻意不可观测,因为 signerInfos 是 DER SET OF;因此解析和验证结果按 DER 顺序而非请求顺序给出
单签名者构建与单容器合并会逐字节保留原有 CMS 内容
独立校验
HPDFParseCMSSignatures、HPDFVerifyCMSSignaturesEx 和 HPDFVerifyCMSSignerReport 会为每个主签名者返回独立结果,涵盖其属性、摘要与签名策略、匹配的证书、时间戳、会签(counter-signature)和失败状态
某个格式错误或密码学上无效的签名者不会抹掉有效兄弟结果;但只要有一个主签名者未通过,聚合布尔结果就是 false
占位符尺寸估算
HPDFCMSEstimateMultiSignerPlaceholder 在不实际签名的前提下推导每个签名长度,用合成签名值构建精确去重后的静态容器形状,累加动态 callback 预留,最后一次性应用配置好的全局安全余量、对齐、最小值和最大值
THPDFCMSPlaceholderEstimateInfo.SignatureBytes 报告所有主签名者的总和,cpesMixed 表示各签名者使用了不同的估算来源
PDF 工作流边界
多签名者 API 暴露的是通用 CMS 能力,面向那些消费 profile 允许单容器内多个主签名者的应用
许多 PDF 签名和 PAdES 工作流在每个签名字典中只建模一个主签名者,所以除非接收方 profile 明确接受多签名者 CMS,否则请使用独立的 PDF 签名字段