Concept · Digital signatures
What is PAdES,
and how do PDF signatures work?
A PAdES signature is a cryptographic seal inside a PDF. It proves three things at once: who signed, that the document has not changed by even a single byte since, and optionally when it was signed. This guide explains digital signatures in plain language, with analogies and examples.
The simplest analogy: a wax seal on an envelope
For centuries a wax seal did two jobs at once. The unique stamp showed who sent the letter, and the unbroken wax showed that nobody opened it on the way. Break the seal and it is obvious.
A digital signature is a wax seal made of mathematics. Instead of a stamp, the signer uses a private key that only they hold; instead of wax over the flap, the seal covers every byte of the document. Anyone can check it with the signer's public certificate, and if so much as a comma changes afterward, the seal visibly breaks. PAdES is the agreed-upon way to put that seal inside a PDF.
Why a real signature is more than an image
A scanned signature is a picture: copy it onto anything and it proves nothing. A digital signature is bound to the exact content. Change a single byte and verification fails, which is what makes it tamper-evident.
If one byte is altered
An attacker edits an amount after signing.
Untouched since signing
Every byte matches the sealed original.
How signing and verifying actually work
Under the hood it is public-key cryptography. The document is reduced to a fingerprint (a hash), the private key seals that fingerprint, and anyone can confirm the seal with the public certificate.
1 · Hash
The exact bytes are reduced to a unique SHA-256 fingerprint.
2 · Sign
The private key seals the fingerprint into a PKCS#7 / CMS structure.
3 · Verify
Anyone re-hashes the file and checks the seal with the public certificate.
rust-pdf signs by appending an incremental update, so the original bytes stay intact. That is what lets multiple people sign the same document without breaking each other's signatures.
The PAdES levels: from basic to long-term
PAdES baseline levels stack on top of each other. Each one adds what is needed to keep the signature verifiable further into the future.
Basic
The signature plus a reference to the signing certificate. Proves who signed and that nothing changed.
+ Timestamp
Adds a trusted RFC 3161 timestamp, proving the document existed and was signed at a specific time.
+ Long-term validation
Embeds the certificates and revocation data (a DSS), so the signature still verifies years later even if the authority disappears.
+ Archive timestamp
Adds a document timestamp over everything, protecting the whole package for the very long term.
rust-pdf produces B-B, B-LT and B-LTA offline, with RFC 3161 timestamps,
a DSS, visible and multiple signatures, validated by pdfsig and
openssl cms.
Where PAdES signatures are used
Anywhere a document must be provably authentic and unaltered, and in much of the world this carries explicit legal weight.
Contracts
Sign agreements with proof of identity, integrity and time, with non-repudiation built in.
eIDAS & public sector
PAdES is the PDF signature profile referenced by EU eIDAS and used across government services.
Invoices & tax
Many e-invoicing regimes require a signed PDF so the tax document cannot be altered after issue.
How to sign a PDF with rust-pdf
Pass the PDF bytes, your private key and certificate (DER), and a flag for PAdES. The signature is appended as an incremental update, then optionally extended to long-term levels.
# pip install rustpdf
import rustpdf
pdf = open("contract.pdf", "rb").read()
key = open("signing-key.pkcs8.der", "rb").read()
cert = open("signing-cert.der", "rb").read()
signed = rustpdf.sign(pdf, key, cert, reason="Approved", pades=True) # PAdES-B-B
lt = rustpdf.add_dss(signed, certs=[cert], crls=[crl]) # -> B-LT
lta = rustpdf.timestamp(lt, tsa_key, tsa_cert) # -> B-LTA
open("contract.signed.pdf", "wb").write(lta)
# Verify in a shell: pdfsig contract.signed.pdf -> "Signature is Valid."
// dotnet add package RustPdf
using RustPdf;
byte[] signed = Pdf.Sign(pdf, keyDer, certDer, reason: "Approved", pades: true); // B-B
byte[] lt = Pdf.AddDss(signed, certs: new[]{ certDer }, crls: new[]{ crl }); // B-LT
byte[] lta = Pdf.Timestamp(lt, tsaKeyDer, tsaCertDer); // B-LTA
// go get github.com/rustpdf/rustpdf-go@latest
signed, _ := rustpdf.Sign(pdf, key, cert, rustpdf.SignOptions{Reason: "Approved", Pades: true})
lt, _ := rustpdf.AddDss(signed, [][]byte{cert}, [][]byte{crl}) // B-LT
lta, _ := rustpdf.Timestamp(lt, tsaKey, tsaCert) // B-LTA
// npm install rustpdf
const { sign, addDss, timestamp } = require("rustpdf");
const signed = sign(pdf, key, cert, { reason: "Approved", pades: true }); // B-B
const lt = addDss(signed, { certs: [cert], crls: [crl] }); // B-LT
const lta = timestamp(lt, tsaKey, tsaCert); // B-LTA
Visible signatures, multiple signers and timestamp details are in the documentation.
PAdES FAQ
What is PAdES?
PAdES stands for PDF Advanced Electronic Signatures. It is the ETSI family of standards (EN 319 142) that defines how to embed a legally robust digital signature inside a PDF. A PAdES signature proves who signed the document, that the document has not changed by even a single byte since signing, and optionally when it was signed. It is the profile referenced by the EU eIDAS regulation for electronic signatures.
How is a digital signature different from a scanned signature?
A scanned or drawn image of a handwritten signature is just a picture: it can be copied onto any document and proves nothing. A digital signature is cryptographic. The signer's private key produces a mathematical seal over the exact bytes of the document, and anyone can verify it with the matching public certificate. If a single byte changes, verification fails, so it proves both identity and integrity.
What do the PAdES levels B-B, B-T, B-LT and B-LTA mean?
They are baseline levels that add longevity. B-B is the basic signature with the signing certificate. B-T adds a trusted timestamp that proves when the document was signed. B-LT (long-term) embeds the validation material, such as certificates and revocation data, so the signature can still be checked years later even if the issuing authority is gone. B-LTA adds an archive timestamp over everything for very long-term integrity.
Is a PAdES signature legally valid?
PAdES is the PDF signature profile referenced by the EU eIDAS regulation, and equivalent frameworks exist worldwide. Legal weight depends on the type of certificate used (for example a qualified certificate for a qualified electronic signature). The PAdES format itself provides the technical proof of identity, integrity and time that regulations require.
How do I sign a PDF with rust-pdf?
Call rustpdf.sign with the PDF bytes, your private key and certificate (DER), and pades=True for a PAdES-B-B signature. The library appends an incremental update so the original bytes are preserved, which keeps earlier signatures valid. add_dss and timestamp then extend it to B-LT and B-LTA. Signatures are checked with pdfsig and openssl cms.
Sign PDFs in your language
One core, the same PAdES signatures across nine languages. Signatures and long-term validation are part of the Enterprise license.