polycratia

A verification check came back invalid on a document that had been signed months earlier.

Nothing in the signing path had changed. The signature was intact, and the certificate and the keys were fine.

What changed was the renderer. A template tweak moved a field in the layout: cosmetic, reviewed, harmless. But the signature had been computed over a PDF rendered on demand, not over a stored artifact. Re-render, new bytes, new hash, failed verification.

So every document signed before that deploy was suddenly unverifiable. That is not something you quietly repair. A signature is a claim about exact bytes, and you cannot go back and ask people to sign history again.

The bug itself was one design decision made long before: hash what gets rendered instead of hashing what gets stored.

Now anything signed is frozen first. Render once, persist the exact bytes, hash those bytes, sign the hash. Verification does not re-render. The template can change as often as anyone wants, because the signed object no longer depends on it.

The general version I keep coming back to: if a value is part of a legal or financial guarantee, it has to be stored, not recomputed. Recomputation makes that guarantee a function of your current code, and your current code moves.

Somewhere in your system there is probably still a value you recompute when you should have stored it...

react

$ new-project --brief

or email hey@polycratia.com