THotPDF.SignPDFWithPFX

THotPDF

 

قبلی  متدها  AddPubKeyRecipient

یک placeholder موجود در PDF را با استفاده از فایل PFX / PKCS#12 امضا می‌کند، یک container از نوع CMS SignedData می‌سازد و PDF امضاشده را در یک فراخوان می‌نویسد

 

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 نقطه ورود end-to-end امضای PFX است که در v2.119.27 اضافه شد. PDF ورودی باید از قبل یک placeholder امضا داشته باشد که توسط THPDFPage.AddSignedSignatureField یا wrapper PAdES آن با subFilter adbe.pkcs7.detached emit شده باشد. این روش:

 

1. PDF ورودی را بارگذاری می‌کند، placeholderهای sentinel مربوط به /ByteRange و /Contents را پیدا می‌کند، و /ByteRange را با offsetهای واقعی بایت patch می‌کند

2. فایل PFX را بارگذاری می‌کند و با password داده‌شده آن را رمزگشایی می‌کند. PBES2 با PBKDF2-HMAC-SHA-256 + AES-256-CBC پشتیبانی می‌شود، که رفتار پیش‌فرض برای فایل‌های PFX صادرشده از OpenSSL 3.0+، Windows 11+ certutil و macOS Keychain Access است. فایل‌های قدیمی PBE-SHA1-3DES یک diagnostic می‌دهند؛ دوباره export کنید با openssl pkcs12 -export ... -keypbe AES-256-CBC -certpbe AES-256-CBC

3. روی bytes سندی که /ByteRange پوشش می‌دهد SHA-256 محاسبه می‌کند و یک blob از نوع CMS SignedData (RFC 5652) DER می‌سازد که شامل certificate X.509، attributeهای امضاشده (contentType + messageDigest + signingTime) و امضای RSA + SHA-256 روی attributeهای امضاشده با برچسب SET است

4. CMS DER را hex-encode می‌کند، بررسی می‌کند که در budget /Contents رزروشده توسط AddSignedSignatureField جا می‌شود (8 KB پیش‌فرض برای RSAهای 1024 / 2048-bit کافی است)، و آن را در placeholder تزریق می‌کند

5. bytes patch‌شده را در مسیر خروجی یا stream می‌نویسد

 

در صورت موفقیت True برمی‌گرداند. روی password نادرست، profile رمزنگاری پشتیبانی‌نشده یا PFX خراب، EHPDFPFXError می‌دهد؛ وقتی PDF ورودی placeholder مورد انتظار را نداشته باشد یا CMS DER از budget /Contents رزروشده بزرگ‌تر شود EHPDFCMSError می‌دهد؛ و روی mismatch کلید RSA EHPDFRSAError می‌دهد

 

گردش‌کار معمول

 

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');

 

یادداشت‌ها

الگوریتم امضا RSA + SHA-256 است (1.2.840.113549.1.1.1 + 2.16.840.1.101.3.4.2.1). شناسه signer از IssuerAndSerialNumber استخراج‌شده از certificate X.509 می‌آید. encapContentInfo جداست و eContent حذف می‌شود. attributeهای امضاشده پیش از hash شدن بر اساس رشته بایت DER صعودی و طبق RFC 5652 §5.4 مرتب می‌شوند

 

برای گردش‌کارهای PAdES B-T / B-LT / B-LTA که به timestampهای RFC 3161، واژه‌نامه‌های DSS یا امضای document timestamp نیاز دارند، helperهای سمت producer (AddPAdESSignatureField، AddPAdESDSSCertificate، AddDocumentTimestampSignature) همچنان کاربرد دارند؛ خود SignPDFWithPFX یک امضای پایه فقط CMS صادر می‌کند، معادل PAdES-B-B

 

See also: AddSignedSignatureField, PreparePDFForSigning, InsertSignatureHex, AddPAdESSignatureField