2.0.0
The first stable release of the standalone package: signing, validation and the
command line, with no framework anywhere in src/.
composer require lsnepomuceno/signet-pdf:^2Read UPGRADE.md
before moving from 1.x. Every breaking change is answered there with the
replacement rather than the removal.
The whole of what changed is in
CHANGELOG.md.
The headlines:
- Signing appends a revision, never a rebuild, so an earlier signature,
every annotation and every form field survive a second one. - The private key does not have to be in this process. Signing is
prepare()andcomplete(): the first appends the revision and fills the
/ByteRange, which is where the offsets stop moving, and hands back the
digest of the covered bytes. The second is one fixed-width overwrite and
takes no certificate at all, so a key on an A3 token, in an HSM or behind a
cloud service signs where it lives. - PAdES
legacythroughpades-b-lta, including on an encrypted
document: the security store and the archive timestamp are encrypted with
everything else, and only the timestamp token stays in the clear, as
ISO 32000-1 §7.6.2 requires. - Validation needs no
opensslbinary if you do not want it to.
NativeSignatureVerifierchecks the signed attributes, the message digest,
the content type and the ESSsigning-certificate-v2attribute through
ext-openssl, and is checked against the binary on every sample, a foreign
pyHanko document and three tamper cases. - Validation reports the signature policy a signer declared, the
signature-policy-identifierof RFC 5126 §5.8.1. A verifier in Brazil looks
for it before calling a signature ICP-Brasil conformant, and until now an
application could not see it at all. - A signature field can be created, not only filled, with no certificate
involved. - A visible seal keeps PDF/A and PDF/UA conformance, measured with veraPDF
rather than asserted. - Encrypted documents that pack their objects into object streams sign,
which is what a password-protected export from a word processor looks like. - ICP-Brasil identity, including the alphanumeric CNPJ that takes effect in
2026.
Documentation: lsnepomuceno.github.io/signet-pdf.
The 1.x documentation is archived at
/v1/.
This tag was re-cut on 2026-08-20. A 2.0.0 published two days earlier
pointed at an earlier commit, and work kept merging after it: two-phase
signing, the signature policy above, and a fix to the document security store,
which keyed its entries by a signature recovered with a trailing-zero trim and
so filed the validation material of about one signature in 256 under a hash of
something that does not exist. If you installed 2.0.0 in that window,
composer update lsnepomuceno/signet-pdf gets the release this page describes.