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

Everything is free.

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.

Is signing free in PHP?

Signing is free, like every feature in rust-pdf.

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.