Sign a PDF in Python so Adobe shows a green tick (PAdES + LTV)
If you've ever signed a PDF from code and then opened it in Adobe Reader only to see a yellow question mark instead of a green tick, you know the pain. Getting Adobe to render "Signed and all signatures are valid" with t
If you've ever signed a PDF from code and then opened it in Adobe Reader only to see a yellow question mark instead of a green tick, you know the pain. Getting Adobe to render "Signed and all signatures are valid" with the green check takes more than a CMS signature β you need PAdES, a trusted timestamp, long-term validation (LTV), and the right in-document appearance.
ATick does all of that in a few lines.
Install
pip install atick
One self-contained package β no system dependencies to chase.
Sign with a green tick, timestamp and LTV
import atick
pdf = open("document.pdf", "rb").read()
pfx = open("my_certificate.pfx", "rb").read()
signed = atick.sign_pfx(
pdf, pfx=pfx, password="your-password",
style=atick.Style(cn="Axonate Tech", reason="Approved"),
placements=[(1, (300, 55, 575, 175))], # page 1, rect (x1, y1, x2, y2)
pades=True, timestamp=True, ltv=True, # PAdES-B-LT
)
open("signed.pdf", "wb").write(signed)
Open signed.pdf in Adobe Reader β with a trusted certificate it shows the green tick and "Signed and all signatures are valid."
-
pades=Trueβ an ETSI PAdES signature -
timestamp=Trueβ RFC-3161 trusted timestamp (PAdES-B-T) -
ltv=Trueβ embeds the chain + revocation for long-term validation (PAdES-B-LT)
Add lta=True for a document timestamp on top (PAdES-B-LTA).
More than the basics
ATick is batteries-included, so the hard parts are one option each:
- The Adobe-valid green tick, built in β most libraries leave the visual appearance to you.
-
USB token / smart-card / HSM via PKCS#11 β
atick.sign_pkcs11(...). -
The Windows certificate store β
atick.sign_winstore(...). -
Deferred / remote-key / eSign β
atick.prepare_deferred(...)thenatick.embed(...). - Certified (no-changes) signatures, encrypted output, and a fully customizable appearance (logo, colours, layout).
And the same API exists in Java, .NET, Node.js and PHP β learn it once, use it everywhere.
Error handling
try:
signed = atick.sign_pfx(pdf, pfx=pfx, password="wrong", style=style, placements=placements)
except atick.AtickError as e:
print("signing failed:", e)
Links
- Docs: https://atick.readthedocs.io/docs/python/
- PAdES & LTV: https://atick.readthedocs.io/docs/python/pades/
ATick is free under AGPL-3.0 (a commercial license is only needed to resell it). A product by Axonate Tech.
Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes β full credit and traffic to the original publisher.
