TCmsSignerIdKind = (sidIssuerAndSerial, sidSubjectKeyIdentifier);
TCmsSignerId = record
Kind: TCmsSignerIdKind;
IssuerDer: TBytes;
SerialDer: TBytes;
SubjectKeyId: TBytes;
end;
ICmsSigner = interface
function GetDigestAlgorithmOid: AnsiString;
function GetSignatureAlgorithmOid: AnsiString;
function GetSignatureAlgorithmParams: TBytes;
function GetSignerId: TCmsSignerId;
function SignSignedAttrsDigest(const Digest: TSHA256Digest): TBytes;
end;
TCmsBuildOptions = record
SigningTimeUtc: TDateTime;
CommitmentTypeOid: AnsiString;
SignaturePolicyOid: AnsiString;
SignaturePolicyHash: TBytes;
SignaturePolicyUri: AnsiString;
SignaturePolicyDocument: TBytes;
class function Default: TCmsBuildOptions; static;
end;
function VerifyCmsSignaturePolicyDocument(const Options: TCmsBuildOptions;
const PolicyDocument: TBytes; out ErrorText: string): Boolean;
function BuildSignedData(const DetachedDigest: TSHA256Digest;
const Signer: ICmsSigner; const SignerCertDer: TBytes;
const ChainCertDer: array of TBytes;
const Options: TCmsBuildOptions): TBytes;
function ExtractSignatureValue(const CmsDer: TBytes;
out SignatureValueOctets: TBytes): Boolean;
procedure AddSignatureTimestampToCms(var CmsDer: TBytes;
const TimestampTokenDer: TBytes);
FPdfCms 是 PAdES 签名路径在内部使用的底层 CMS 构建器。它允许高级用户从已签名属性的 SHA-256 报文摘要、一个签名器抽象、签名器证书以及一个可选的证书链来组装一个 CMS SignedData 值
ICmsSigner 接口是加密后端契约:调用方提供摘要与签名算法 OID、签名器标识符,并对已签名属性摘要执行真正的私钥运算。这将 CMS 编码与任何特定的加密提供程序解耦
TCmsBuildOptions 可以添加签名时间、承诺类型,以及带 SHA-256 策略哈希、URI 和可选内存中策略文档的显式签名策略标识符
ExtractSignatureValue 从一个已完成的 CMS 值中提取原始签名字节,以便发送给时间戳机构;AddSignatureTimestampToCms 随后将返回的时间戳令牌作为无符号属性嵌入,生成符合 B-T/B-LTA 的形式
| Method | Description |
|---|---|
GetDigestAlgorithmOid | 返回对已签名属性所使用的哈希算法 OID(例如 SHA-256 的 2.16.840.1.101.3.4.2.1) |
GetSignatureAlgorithmOid | 返回应用于摘要的签名算法 OID |
GetSignatureAlgorithmParams | 返回算法参数(ECDSA 时通常为空;PSS 时承载 RSA-PSS 参数块) |
GetSignerId | 返回按颁发者/序列号或按主体密钥标识符标识签名器的 TCmsSignerId |
SignSignedAttrsDigest | 对提供的摘要执行私钥签名并返回签名字节 |
| Routine | Description |
|---|---|
CertKeyAlgorithmOid | 从证书中读取 SubjectPublicKeyInfo 算法 OID——RSA 和 ECDSA 两种签名算法正是由它决定的;每个签名后端都需要它,所以把它放在这里,而不是塞进其中某个后端 |
ExtractIssuerAndSerial | 提取 SignerIdentifier 携带的原始 issuer 与 serialNumber TLV,写入 IssuerTlv 和 SerialTlv |
EcDsaP1363ToDer | 把 P1363 r||s 形式的原始 ECDSA 签名封装成 CMS 期望的由两个 INTEGER 组成的 DER SEQUENCE;令牌和平台加密 API 返回的都是原始形式 |
VerifyCmsSignaturePolicyDocument | 要求非空的 SignaturePolicyOid 和 32 字节的 SignaturePolicyHash,然后用 SHA-256 验证所提供的策略文档,并在失败时返回诊断文本 |
BuildSignedData | 构建带有一个 CAdES SignerInfo、签名器证书、可选链和已配置签名属性的完整分离式 RFC 5652 CMS ContentInfo |
ExtractSignatureValue | 提取用作 RFC 3161 时间戳报文印鉴输入的原始 SignerInfo 签名字节 |
AddSignatureTimestampToCms | 把完整的 RFC 3161 TimeStampToken 添加为签名时间戳无符号属性,并重新编码外层长度 |
| Type | Description |
|---|---|
TCmsSignerIdKind | sidIssuerAndSerial 选择颁发者 Name 加序列号 TLV,sidSubjectKeyIdentifier 选择原始主体密钥标识符字节 |
TCmsSignerId | Kind、IssuerDer、SerialDer 和 SubjectKeyId 承载选定的 SignerInfo 标识形式 |
TCmsBuildOptions | SigningTimeUtc、CommitmentTypeOid、SignaturePolicyOid、SignaturePolicyHash、SignaturePolicyUri 和 SignaturePolicyDocument 配置签名属性;Default 清空每个可选值 |
TSHA256Digest 由 FPdfSha256 单元提供BuildSignedData 将证书链作为 DER 编码证书的开放数组接收,不要求签名者排在最前;顺序遵循 CMS EncapsulatedCertificateSet