PD4ML PDF Signing
PD4ML PDF Signing adds digital signatures to existing PDF files, from Java code or from the command line. The signature is appended as an incremental update: every byte of the original file stays unchanged, and the signature field, the CMS signature and an optional visible appearance are written after it. The private key can come from a PKCS#12 keystore, a PKCS#11 hardware token or HSM, or a cloud KMS.
Available from PD4ML v4.1.1, in the com.pd4ml.pdf.sign package. It uses BouncyCastle (bcprov/bcpkix) for the cryptography, so the BouncyCastle jars must be on the classpath.
What you can do with it
- Sign a PDF with an invisible signature, or with a visible signature widget showing a stamp image (PNG/JPEG), caption text, or both, at a given page and rectangle.
- Use the key where it lives: a PKCS#12 (
.p12/.pfx) file, a PKCS#11 token or HSM (the key never leaves the token), or a cloud KMS through the one-methodRemoteSignerinterface (API only, not in the command-line tool). - Certify a document (DocMDP) at one of three levels: no changes allowed, form filling allowed, or form filling and annotations allowed. Only the first signature on a document can certify it.
- Co-sign: add further signatures to an already signed, uncertified document, each in its own signature field.
- Add an RFC 3161 timestamp from a TSA, with optional HTTP Basic Auth.
- Add long-term validation (PAdES-LT): embed the certificate chain and OCSP responses and/or CRLs in a
/DSSdictionary, right after signing or later, on a PDF signed by this tool or by any other PAdES-compliant signer. - Choose the digest: SHA-256 (default), SHA-384 or SHA-512; RSA or ECDSA follows from the certificate's key type.
- List the signature fields of a PDF with their status, signer data and certification level.
Quick start
Sign a PDF with a PKCS#12 key, a visible signature on the first page and a timestamp:
import com.pd4ml.pdf.sign.*;
import java.io.File;
CertificateUtils.SigningIdentity identity =
CertificateUtils.loadFromPkcs12(new File("signer.p12"), "changeit".toCharArray());
SigningOptions options = new SigningOptions()
.setReason("Approved")
.setSignerName("Jane Doe")
.setTsaUrl("http://timestamp.digicert.com")
.setVisibleSignatureOptions(new VisibleSignatureOptions()
.setPage(0) // zero-based
.setRectangle(36, 36, 220, 70) // llx, lly, width, height in points
.setVisibleText("Jane Doe"));
new PdfSigner().sign(new File("in.pdf"), new File("out.pdf"), identity, options);
Every failure is reported as a single checked PdfSigningException.
The same from the command line, with long-term validation added in the same call (on Windows, separate the classpath entries with ;):
java -cp "pd4ml.jar:bouncycastle-runtime-1.84.jar" com.pd4ml.pdf.sign.cli.PdfSignCli sign in.pdf out.pdf \
--p12=signer.p12 --password=changeit --reason=Approved --signer="Jane Doe" \
--tsa=http://timestamp.digicert.com --visible --page=0 --rect=36,36,220,70 --text="Jane Doe" \
--ltv
When to use it
Use PD4ML PDF Signing when a finished PDF needs a digital signature, a certification or long-term validation data. The other PDF tools prepare documents; signing is normally the last step.
| Tool | Use it to |
|---|---|
| PD4ML PDF COS | read, inspect, query and modify PDF objects; the foundation the other tools are built on |
| PD4ML PDF Merge | combine page ranges from several PDFs into one |
| PD4ML PDF Optimizer | make existing PDFs smaller |
| PD4ML PDF XFDF | import and export form field values and annotations as XFDF |
A signature covers the exact bytes of the file as it was signed. Merge and the optimizer write a new file rather than an incremental update on top of the old one, so merge and optimize first, then sign. An encrypted input PDF is refused: the signer can read encrypted files but cannot write back into them. LTV data is added as a further incremental update and does not touch the signature.
In this section
- PD4ML PDF COS/Signing API - Programmer's Manual: how a signature is applied,
PdfSigner,SigningOptionsandVisibleSignatureOptions, key sources, DocMDP certification, placeholder sizing, timestamps, PAdES-LT, error messages and thread safety. - Examples: 18 runnable use-case classes, from a minimal invisible signature to PKCS#11, cloud KMS, co-signing and LTV on a PDF signed elsewhere.
- pdfsigncli - Command-Line Reference: the
inspect,fields,signandltvcommands, all options, exit codes and troubleshooting. - Javadoc for
com.pd4ml.pdf.sign: the API reference.
