Digital signatures · PHP

Digitally sign a PDF in PHP

Add a cryptographic PKCS#7 or PAdES signature to a PDF from PHP. rust-pdf signs through a non-destructive incremental update, so the original bytes are preserved and the signature stays verifiable in Adobe Reader, pdfsig and any PAdES validator.

Last updated: 2026-06-29

Why PHP needs this

A scanned signature image proves nothing. A cryptographic signature binds a named certificate to the exact bytes of the document and reveals whether a single byte changed afterwards. That is the difference between decoration and legal evidence.

rust-pdf signs through a non-destructive incremental update, building the detached CMS by hand to control the ByteRange. It supports PKCS#7 and PAdES B-B, plus B-LT and B-LTA for long-term validation, and accepts your own PKCS#8 key and X.509 certificate as DER, so the signing material never leaves your own infrastructure.

Because the call is pure CPU work, the natural pattern is a queued Laravel job or Symfony Messenger handler that signs after upload and never blocks the web request. There is no openssl or Java signing service to orchestrate: composer require pulls in the binding, ext-ffi bridges to the core, and pdfsig confirms the result on the shell.

  • PKCS#7 detached and PAdES B-B, with B-LT and B-LTA for long-term validation.
  • Incremental update: the original file is preserved byte for byte, so earlier signatures stay valid.
  • Bring your own key and X.509 certificate (PKCS#8 DER), or chain to a TSA for timestamps.

Sign a PDF in PHP with rust-pdf

Pull in the package with Composer, then use the same idiomatic API shared by every rust-pdf binding. The signing snippet below is taken straight from the PHP reference.

composer require rust-pdf/rustpdf

PHP
use RustPdf\Pdf;

$pdf     = file_get_contents('contract.pdf');
$keyDer  = file_get_contents('signing-key.pkcs8.der');   // PKCS#8 private key (DER)
$certDer = file_get_contents('signing-cert.der');        // X.509 certificate (DER)

$signed = Pdf::sign($pdf, $keyDer, $certDer,
    reason: 'Approved', location: 'New York',
    name: 'Jane Doe', pades: true);
file_put_contents('contract.signed.pdf', $signed);
// Verify in a shell: pdfsig contract.signed.pdf  →  "Signature is Valid."
Validated by: pdfsigopensslqpdf

Generation is free in PHP; signing is a corporate feature that one offline license token unlocks. See pricing & licensing.

The complete signing API is in the PHP documentation.

Signing in PHP: FAQ

Is the signature legally valid?

rust-pdf produces standards-compliant PKCS#7 and PAdES signatures. Legal validity depends on the certificate you sign with (for example an eIDAS qualified certificate or an ICP-Brasil certificate). The library handles the cryptography and the PDF structure correctly, which is what validators such as pdfsig and Adobe Reader check.

Does it support long-term validation (LTV)?

Yes. After signing you can append a Document Security Store with certificates and CRLs (PAdES B-LT) and an RFC 3161 document timestamp (PAdES B-LTA), all offline. A trusted external TSA and live OCSP fetching are the only parts that need network infrastructure.

Do I need a license to sign in PHP?

Signing is a corporate feature, so it requires an active license token. Basic PDF generation in PHP is free. The same offline Ed25519 token unlocks signing across every language.

Can I sign with a PKCS#12 / .pfx certificate in PHP?

The signer takes a PKCS#8 private key and an X.509 certificate as DER byte strings. If you hold a .pfx or .p12, split it once with openssl (pkcs12 -nocerts for the key, -clcerts -nokeys for the cert) and convert the PEM to DER, then pass both to Pdf::sign. The usual pattern is a queued Laravel job so signing never blocks the web request.

Put verifiable signatures into your PHP workflow

One Rust core, the same signatures in every language. Develop against the full signing API, and activate a license token when you put signed documents into production.