Driver's license barcode signatures are unverifiable

Published: September 18, 2026

The signature on a driver's license barcode cannot be checked.

Nobody outside the issuing state holds the key that would prove the card genuine.

On 16 September, security researcher Ryan Fahey published a write up called Keys Not Included, and his own summary of the work is short.

Several states sign the data in their driver's license barcodes, and publish no keys that would let anyone check those signatures.

He recovered the missing keys from the signatures themselves, using ECDSA key recovery.

A PDF417 barcode symbol, the format that carries driver's license barcode data

PDF417 symbol by BaptisteGrandGrand, CC BY-SA 4.0, via Wikimedia Commons.

A signature that ships without a published key is not verification, it is a claim only the signer can audit.

What a driver's license barcode actually proves

A signature means nothing on its own, and only earns its keep against a key you already trust.

That key has to reach you through a channel an attacker does not control, which is why certificate authorities, package registries, and trust stores exist at all.

When the barcode ships no key, a verifier is left with two options: trust the payload, or work backwards from the signature.

Working backwards is ordinary, documented ECDSA behavior rather than a break of it.

Given a signature and the message it covers, public key recovery returns candidate keys, so a signature can always be explained by some key.

Every forged barcode explains itself just as neatly as a genuine one, which is the part that should worry anyone who reads cards for a living.

A handheld barcode scanner of the kind used to read the back of a driver's license

A scanner doing recovery is checking that arithmetic was performed correctly, not that a state agency wrote the record.

The issuing authority keeps the only vantage point from which the signature settles anything, and the card gives a stranger no way to stand there.

He made a related argument in December 2025, in a post titled Insecure by Design, where he argues that the standard itself is insecure by design and that the same organization sells the remedy.

How the check degrades in practice

At the counter the flow is a scan, a parse, and a green tick, and the tick is the part everyone remembers.

Nothing in that flow separates a state issued record from one a forger wrote, because both arrive with a signature that satisfies the same arithmetic.

The step that would catch a forgery, a human comparing a face to a photograph, tends to get skipped once software has said yes.

Meanwhile the payload lands in a log, so a scan creates an identity record with a retention problem attached and very little verification value to show for it.

The failure shape is familiar

This is the same gap that opens whenever a signing scheme ships without its distribution problem solved.

Artifacts arrive signed by a builder that no verifier has a key for, tokens carry signatures that nobody pins, and updates get accepted because the check returned true rather than because the signer was identified.

The pattern repeats: the cryptography holds up, the key distribution was never shipped, and the check quietly degrades into a format validator.

What teams reading the cards should change

Identity checks at a counter, an age gate, and a signup form all consume the scanned payload as though it were a fact.

If a signature cannot carry that weight, something else has to, and it is usually something you already control.

1. Pin the key, or delete the claim

If your verification path recovers the key it checks against, that path proves nothing and should be removed before it is trusted again.

Real verification needs a public key you obtained from the issuer over a channel you control, stored locally and rotated on a schedule, which is the same authentication and authorization plumbing you already run for tokens.

2. Treat the scanned payload as hostile input

A barcode is attacker controlled data in a rigid format, so parse it the way you parse any other request body, with API security habits rather than optimism.

Reconcile the parsed fields against a record you hold, log the raw payload, and put the parsing rules through the same review path as every other developer security practice.

3. Ask vendors which key they validate against

When a product claims it validates barcode signatures, ask which key it validates against and how that key reached the device.

We verify the signature is not an answer, and if the card eventually moves to a phone, the same question about keys and issuers follows it there.

What a working version looks like

An offline signature is a good idea when the alternative is a network call that leaks who is checking whom.

It only works if the issuer publishes the keys, dates them, and says what to do when one is retired.

Cards have long lives, so rotation and revocation stop being paperwork and become the thing that decides whether an old forgery still passes.

That is a real commitment, and it is the piece that is usually missing, because publishing a key is easy and retiring one is not.

Procurement is where this gets fixed, because a vendor selling a check that cannot check is selling the appearance of one.

Ask for the trust anchor, the rotation policy, and what the product does when verification is impossible rather than merely unsuccessful.

Until then, treat the barcode as a convenient carrier for data you still have to confirm, not as a verdict.

That reordering is uncomfortable, because it puts the cost of a fake ID back on the business accepting it.

The assumption and the replacement

The old assumption was that a signed field is a verified field.

The replacement is that a signature proves authorship only to someone who already knows the author, and everyone else is reading a checksum.

Where in your stack does a scanned ID stop being data and start being truth?