Inspect and Sign PDF Documents Safely with pdfsig
You will finish with a repeatable way to inspect a PDF's digital signatures and, when you have a suitable certificate, write a newly signed copy without changing the source document. The examples use pdfsig from Poppler 24.02.0, installed here as poppler-utils 24.02.0-1ubuntu9.9.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about fifteen minutes for inspection. Signing takes longer if you need to identify an NSS certificate or use a hardware token. You need a shell, a readable PDF and the poppler-utils package. Signature verification can perform online OCSP checks, so use a network and trust store appropriate for the document. The signing examples require an already configured certificate and private key; this guide does not create or import credentials.
1. Confirm the installed command
Start with read-only checks. They do not need elevated privileges:
$ command -v pdfsig
/usr/bin/pdfsig
$ pdfsig -v
pdfsig version 24.02.0
Copyright 2005-2024 The Poppler Developers - http://poppler.freedesktop.org
The option spelling and output belong to the installed version. If your version differs, read its local manual before copying a signing command into a script.
Checkpoint: make sure the input is the document you intend to inspect:
$ test -r /path/to/document.pdf && echo 'input is readable'
input is readable
$ file /path/to/document.pdf
/path/to/document.pdf: PDF document, version 1.7
Use a path rather than relying on the current directory when working with downloaded or shared files. Do not run sudo pdfsig as a routine step. Root access does not make a certificate trustworthy and can expose credentials through a different home directory.
2. Inspect signatures without changing the PDF
Pass the PDF as the only positional argument:
$ pdfsig /path/to/document.pdf
The exact output depends on the file. For each signature, look for the signer identity, signing time, digest, signature type, signed byte ranges and whether the whole document is covered. Treat the reported names and validation result as claims to investigate, not as proof that the person or organisation is the one you expected.
A PDF with no signatures may produce no signature records. A damaged, unreadable or unsupported file instead produces an error and a non-zero exit status. Capture the status immediately if a script needs to distinguish success from a message printed to the terminal:
$ pdfsig /path/to/document.pdf
$ status=$?
$ printf 'pdfsig exit status: %s\n' "$status"
pdfsig exit status: 0
Status 0 says that pdfsig completed its operation. It does not make a trusted certificate, a known signer or a fully signed document appear where none exists.
3. Understand the certificate checks
By default, pdfsig uses trusted certificates from its NSS search locations: an explicitly selected directory, the default Firefox profile, or /etc/pki/nssdb. It also uses OCSP to check revocation unless you disable it. This can make inspection depend on network access and local certificate configuration.
If you need to use a particular NSS database, point to it explicitly:
$ pdfsig -nssdir sql:/path/to/nssdb /path/to/document.pdf
The prefix is passed to the NSS database selection mechanism. Use the format used by your certutil setup; do not guess a database directory from a certificate filename.
For an offline diagnostic, you can suppress OCSP while retaining local CRL checks:
$ pdfsig -no-ocsp /path/to/document.pdf
This is not equivalent to a complete trust decision. Record the option in an audit trail and do not use it to hide a network or revocation failure. Similarly, -nocert disables certificate validation. That is useful for isolating a parsing or signature problem, but it must not be reported as a trusted verification.
Some certificate chains omit an intermediate certificate. The installed command can use Authority Information Access to fetch missing certificates:
$ pdfsig -aia /path/to/document.pdf
Fetching certificate material changes the external requests made during verification. Use it only where that network behaviour is acceptable, and prefer a controlled trust store for repeatable checks.
4. Export the embedded signature material
Use -dump when you need the raw CMS or PKCS#7 bundle for separate analysis:
$ mkdir -p /tmp/pdfsig-dump
$ cd /tmp/pdfsig-dump
$ pdfsig -dump /path/to/document.pdf
$ find . -maxdepth 1 -type f -printf '%f\n'
The files are written in the current directory and are commonly unpadded or zero-padded CMS/PKCS#7 data. This is a file-writing operation, but it leaves the PDF untouched. Keep the temporary directory access-controlled if the document contains sensitive signatures, and remove the dump after your separate analysis has finished. Do not mistake the exported bundle for a detached signature that can be applied to an arbitrary PDF.
5. List credentials before attempting a signature
Signing is security-sensitive. It creates a document that other people may rely on, and the private-key password or token interaction must stay under your control. First list the available certificate nicknames in the intended NSS database:
$ pdfsig -nssdir sql:/path/to/nssdb -list-nicks
The output is host-specific. Copy the exact nickname, including spaces, and quote it in the signing command. You can also see the cryptographic backends available to this build:
$ pdfsig -list-backends
pdfsig backends:
NSS (active)
Do not paste a private-key password into shell history, process listings or a ticket. The manual exposes -nss-pwd and -kpw, but a password supplied as an argument can be visible to other local users while the process runs. Prefer the least exposed method supported by your environment, and clear any temporary shell history entry according to your organisation's policy.
6. Add a signature to a new output file
Before changing state, choose a new destination. The command syntax below creates signed-output.pdf from the source and selects an existing certificate:
$ pdfsig /path/to/input.pdf /path/to/signed-output.pdf \
-add-signature \
-nssdir sql:/path/to/nssdb \
-nick 'Example signing certificate' \
-reason 'Approved for release'
$ test -s /path/to/signed-output.pdf && echo 'signed output exists'
signed output exists
The default digest is SHA256. Use -digest only when a documented compatibility requirement calls for another algorithm. -etsi changes the signature type to ETSI.CAdES.detached; it is not a general-purpose quality switch.
This operation may prompt for access to the signing key, depending on the backend and key protection. It can fail after creating an incomplete destination, so never use a valuable existing file as the output path. If it fails, remove only the failed output after checking its path, then retry with a fresh name. The input is your recovery copy and remains untouched.
7. Sign an existing unsigned signature field
A form may already contain an unsigned signature field. In that case, use -sign with its field name or its zero-based position:
$ pdfsig /path/to/input-with-field.pdf /path/to/field-signed.pdf \
-sign 0 \
-nssdir sql:/path/to/nssdb \
-nick 'Example signing certificate' \
-reason 'Approved for release'
The field must exist and be unsigned. Position 0 means the first signature field as understood by pdfsig; it is not a certificate index. If the document has multiple fields, prefer a field name when the producer gives you one, so a change in field ordering cannot select the wrong target.
After either signing workflow, inspect the result as a separate step:
$ pdfsig /path/to/signed-output.pdf
$ printf 'verification command status: %s\n' "$?"
verification command status: 0
Check that the expected signer, reason and signed ranges appear. Keep the original and signed files separately until a recipient has confirmed that the result opens and validates in their software.
Done means
- You confirmed the installed Poppler version and inspected the intended PDF.
- You understand whether the verification used OCSP, local revocation data and a chosen NSS database.
- You treated
-nocertand-no-ocspas diagnostic exceptions, not proof of trust. - You listed and selected the intended certificate without exposing a private-key password unnecessarily.
- You wrote a signed copy to a new path, leaving the source PDF available for recovery.
- You ran
pdfsigon the output and checked the signer and signed ranges.