THotPDF.SignPDFWithPFX

THotPDF

 

이전  메서드  AddPubKeyRecipient

Signs an existing PDF placeholder using a PFX / PKCS#12 file, building a CMS SignedData container and writing the signed PDF in one call.

 

Delphi syntax (file overload):

class function SignPDFWithPFX(

  const InputPDFPath: string;

  const OutputPDFPath: string;

  const PFXFilePath: string;

  const Password: AnsiString): boolean; overload; static;

 

Delphi syntax (stream overload):

class function SignPDFWithPFX(

  InputStream: TStream;

  OutputStream: TStream;

  const PFXFilePath: string;

  const Password: AnsiString): boolean; overload; static;

 

설명

SignPDFWithPFX는 v2.119.27에 추가된 end-to-end PFX signing entry point입니다. Input PDF에는 THPDFPage.AddSignedSignatureField(또는 해당 PAdES wrapper)가 adbe.pkcs7.detached subFilter로 emit한 signature placeholder가 이미 있어야 합니다. 이 method의 흐름은 다음과 같습니다

 

1. Input PDF를 로드하고 /ByteRange + /Contents sentinel placeholder를 찾은 뒤 실제 byte offset으로 /ByteRange를 patch합니다

2. PFX file을 로드하고 제공된 password로 decrypt합니다. PBKDF2-HMAC-SHA-256 + AES-256-CBC를 사용하는 PBES2가 지원됩니다(OpenSSL 3.0+, Windows 11+ certutil, macOS Keychain Access가 export한 PFX file의 기본값). Legacy PBE-SHA1-3DES file은 diagnostic을 raise합니다. openssl pkcs12 -export ... -keypbe AES-256-CBC -certpbe AES-256-CBC로 다시 export하십시오

3. /ByteRange가 cover하는 document byte에 대해 SHA-256을 계산하고, X.509 certificate, signed attributes(contentType + messageDigest + signingTime), SET-tagged signed attributes에 대한 RSA + SHA-256 signature를 포함하는 CMS SignedData(RFC 5652) DER blob을 build합니다

4. CMS DER을 hex-encode하고 AddSignedSignatureField가 예약한 /Contents budget에 들어가는지 확인한 뒤(default 8 KB는 1024 / 2048-bit RSA를 cover) placeholder에 삽입합니다

5. Writes the patched bytes to the output path or stream.

 

Returns True on success. Raises EHPDFPFXError on a bad password, unsupported encryption profile, or malformed PFX; EHPDFCMSError when the input PDF lacks the expected placeholder or the CMS DER overflows the reserved /Contents budget; EHPDFRSAError on RSA key mismatch.

 

Typical workflow

 

Doc := THotPDF.Create(nil);

Doc.FileName := 'unsigned.pdf';

Doc.BeginDoc;

Doc.CurrentPage.AddSignedSignatureField(

  'Sig1', Rect(60, 60, 260, 90), 8192,

  'adbe.pkcs7.detached', 'Approved', 'Brussels', '', []);

Doc.EndDoc;

Doc.Free;

THotPDF.SignPDFWithPFX('unsigned.pdf', 'signed.pdf', 'mykey.pfx', 'mypassword');

 

Notes

Signature algorithm은 RSA + SHA-256(1.2.840.113549.1.1.1 + 2.16.840.1.101.3.4.2.1)입니다. Signer identifier는 X.509 certificate에서 추출한 IssuerAndSerialNumber입니다. encapContentInfo는 detached입니다(eContent omitted). Signed attributes는 hash 전에 RFC 5652 §5.4에 따라 DER byte string 오름차순으로 정렬됩니다

 

RFC 3161 timestamp, DSS dictionary 또는 document timestamp signature가 필요한 PAdES B-T / B-LT / B-LTA workflow에는 producer-side helper(AddPAdESSignatureField, AddPAdESDSSCertificate, AddDocumentTimestampSignature)가 계속 적용됩니다. SignPDFWithPFX 자체는 basic CMS-only signature(PAdES-B-B equivalent)를 emit합니다

 

참조: AddSignedSignatureField, PreparePDFForSigning, InsertSignatureHex, AddPAdESSignatureField