PDFium Delphi Component Docs

FPdfCryptoMac 单元

单元: FPdfCryptoMac
面向 PAdES 签名的 macOS Keychain 后端,并通过 Security.framework 提供 CMS 验证与证书信任评估

语法

EPdfKeychainError = class(Exception);

TPdfKeychainSignerProvider = class(TInterfacedObject, IPadesSignerProvider)
  constructor Create(const KeychainPath: string = '');
  function BackendName: string;
  function Resolve(const Options: TPadesSignerOptions): TPadesResolvedSigner;
end;

TPdfKeychainCmsVerifier = class(TInterfacedObject, IPdfCmsVerifier)
  function BackendName: string;
  function VerifyDetached(const CmsDer: TBytes; Segment1: Pointer; Segment1Length: Cardinal; Segment2: Pointer; Segment2Length: Cardinal; const Options: TPdfCmsVerifyOptions): TPdfCmsVerifyResult;
  function VerifyAttached(const CmsDer: TBytes; const Options: TPdfCmsVerifyOptions): TPdfCmsVerifyResult;
end;

function KeychainAvailable: Boolean;
function KeychainMissingSymbols: string;
function KeychainVerificationAvailable: Boolean;
function ConfigureKeychainSignerProvider: IPadesSignerProvider;
function ConfigureKeychainCmsVerifier: IPdfCmsVerifier;
procedure ConfigureKeychainTrustAnchors(const Anchors: TPadesChainCertArray);
procedure ConfigureKeychainOcspResponses(const Responses: TPadesChainCertArray);

说明

FPdfCryptoMac 是 FPdfCrypto 和 FPdfCms 使用的 macOS 加密后端,它覆盖平台集成的两个部分:通过 Keychain 身份进行 PAdES 签名,以及通过系统 CMS 解码器和信任评估进行 CMS 验证。Security.framework 和 CoreFoundation 在运行时按名称加载并解析符号,而不是链接,因此本单元可以在所有目标平台上编译,并在运行时报告平台服务是否真正可达

在签名一侧,TPdfKeychainSignerProvider 实现 IPadesSignerProvider。它的 Resolve 方法枚举 Keychain 身份,选出证书与 TPadesSignerOptions 携带的 SHA-1 指纹匹配的那一个,读取证书 DER 与对应的私钥引用,并返回 TPadesResolvedSigner,其 ICmsSigner 通过 Security.framework 对 CMS 已签名属性进行签名,因此私钥从不离开 Keychain。选项中请求的填充方案会与密钥实际支持的能力相调和,RSASSA-PSS 参数与其他后端生成的完全相同,因此在 macOS 上签名的文档携带一致的 AlgorithmIdentifier。ConfigureKeychainSignerProvider 构建该提供方并将其安装为活动的 PAdES 签名后端,返回它注册的接口

验证侧的 TPdfKeychainCmsVerifier 基于 CMSDecoder 和 SecTrust 实现 IPdfCmsVerifier。VerifyDetached 将签名空档两侧的两个已签名字节范围拼成解码器要求的分离内容,再验证 CMS;VerifyAttached 验证自带内容的 CMS,时间戳 token 就属于这种形式。两者都返回 TPdfCmsVerifyResult,分别报告签名、信任和吊销状态,可按需收集签名者证书与评估出的证书链,并遵守 TPdfCmsVerifyOptions 中的吊销、在线获取和 checkpoint 设置。ConfigureKeychainCmsVerifier 创建验证器并将其注册为当前 CMS 验证后端

签名有效性与证书信任保持为相互独立的结果,因此不受信任或自签链下的真实签名仍然可与被篡改的内容区分开

对于内嵌的 RFC 3161 token,带上限的 DER 解析会把原始封装的 TSTInfo 字节交给原生解码器,不修改其内容类型或已签名属性。普通 CMS 验证会从原生输入中剔除未签名属性,避免自动时间戳处理替代外层签名自身的完整性或证书链结果。这次验证不检查 countersignature 或其他未签名属性;ValidatePadesTrust 会单独验证各原始时间戳 token、message imprint、TSA 证书角色、信任和吊销结果

向 TPdfKeychainSignerProvider.Create 传入 Keychain 文件路径,可通过仅用于本次查询的搜索列表,将身份查找限定到该 Keychain,再使用 ConfigurePadesSignerProvider 注册提供器。空路径使用当前用户搜索范围。打开或搜索所选 Keychain 不会修改默认 Keychain、用户搜索列表或系统信任配置;无效路径或限定搜索所需符号不可用会抛出 EPdfKeychainError

Resolve 还会通过离线、仅限本次查询的证书查找和原生证书链构建,导出签名证书可取得的签发者链。候选证书最多 4096 个,每个 1 MiB,总计 16 MiB;构建的链最多 32 个证书,包含叶证书,而叶证书与 ChainCertDer 分开返回。导出证书材料不表示信任成立,也不会安装信任锚;无法取得的签发者不能凭空补出

签名函数

函数说明
KeychainAvailable当 Security.framework 和 CoreFoundation 已加载且签名所需的全部符号解析成功时返回 True
KeychainMissingSymbols返回解析失败的名称(以空格分隔),全部绑定成功时返回空字符串
ConfigureKeychainSignerProvider构建 TPdfKeychainSignerProvider,将其安装为 PAdES 签名后端,并作为 IPadesSignerProvider 返回
TPdfKeychainSignerProvider.Create可选地指定已有 Keychain 文件来限定身份查找范围,拒绝内嵌 NUL 字符和超过 4096 个字符串代码单元的路径
TPdfKeychainSignerProvider.BackendName返回签名提供方所报告的后端标识符
TPdfKeychainSignerProvider.Resolve将 TPadesSignerOptions 与 Keychain 身份进行匹配,返回持有签名器、证书 DER 与链的 TPadesResolvedSigner

验证函数

函数说明
KeychainVerificationAvailable当 CMS 解码器、信任策略与信任评估符号解析成功时返回 True
ConfigureKeychainCmsVerifier构建 TPdfKeychainCmsVerifier,将其安装为 CMS 验证后端,并作为 IPdfCmsVerifier 返回
ConfigureKeychainTrustAnchors克隆显式 DER 信任锚,供之后每次信任评估补充系统信任锚,不修改 Keychain;上限为 64 个证书、每证书 4 MiB、总计 16 MiB,空数组清除配置
ConfigureKeychainOcspResponses克隆显式 DER OCSP 证据,供原生 Security.framework 评估;上限为 8 个响应、每响应 1 MiB、总计 4 MiB,空数组清除配置
TPdfKeychainCmsVerifier.BackendName返回验证后端所报告的后端标识符
TPdfKeychainCmsVerifier.VerifyDetached使用给定的 TPdfCmsVerifyOptions,针对由 Segment1、Segment1Length、Segment2 和 Segment2Length 描述的两个调用方内容段验证分离的 CMS 值
TPdfKeychainCmsVerifier.VerifyAttached使用给定的 TPdfCmsVerifyOptions,验证携带自身已签名内容的附着 CMS 值

类型

类型成员与用途
EPdfKeychainError当 Security.framework 不可用、没有 Keychain 身份与请求的签名器匹配,或平台签名调用失败时抛出的异常
TPdfKeychainSignerProvider实现 IPadesSignerProvider 的 PAdES 签名后端,包含 BackendName 与 Resolve
TPdfKeychainCmsVerifier实现 IPdfCmsVerifier 的 CMS 验证后端,包含 BackendName、VerifyDetached 与 VerifyAttached

备注

参见

FPdfCryptoWin, FPdfCrypto, FPdfCryptoOcsp, FPdfCms, FPdfTrustedList, FPdfMac