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 可加入簽署時間、commitment 類型,以及具 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 | 建構完整的分離式 RFC 5652 CMS ContentInfo,包含單一 CAdES SignerInfo、簽署者憑證、可選憑證鏈與設定的已簽屬性 |
ExtractSignatureValue | 擷取原始 SignerInfo 簽章八位元組,作為 RFC 3161 時間戳記訊息印記的輸入 |
AddSignatureTimestampToCms | 將完整的 RFC 3161 TimeStampToken 加入為 signature-time-stamp 未簽署屬性,並重新編碼外層長度 |
| 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