PDFium Delphi Component 文件

FPdfCms 单元

单元: FPdfCms
构建 RFC 5652 CMS / CAdES SignedData 结构,验证签名策略文档,并嵌入可选的 RFC 3161 时间戳

语法

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 的形式

ICmsSigner 方法

MethodDescription
GetDigestAlgorithmOid返回对已签名属性所使用的哈希算法 OID(例如 SHA-256 的 2.16.840.1.101.3.4.2.1)
GetSignatureAlgorithmOid返回应用于摘要的签名算法 OID
GetSignatureAlgorithmParams返回算法参数(ECDSA 时通常为空;PSS 时承载 RSA-PSS 参数块)
GetSignerId返回按颁发者/序列号或按主体密钥标识符标识签名器的 TCmsSignerId
SignSignedAttrsDigest对提供的摘要执行私钥签名并返回签名字节

函数与过程

RoutineDescription
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 添加为签名时间戳无符号属性,并重新编码外层长度

类型

TypeDescription
TCmsSignerIdKindsidIssuerAndSerial 选择颁发者 Name 加序列号 TLV,sidSubjectKeyIdentifier 选择原始主体密钥标识符字节
TCmsSignerIdKind、IssuerDer、SerialDer 和 SubjectKeyId 承载选定的 SignerInfo 标识形式
TCmsBuildOptionsSigningTimeUtc、CommitmentTypeOid、SignaturePolicyOid、SignaturePolicyHash、SignaturePolicyUri 和 SignaturePolicyDocument 配置签名属性;Default 清空每个可选值

备注

参见

FPdfTsa, FPdfCrypto, FPdfSha256, TPdf.SignPades