Skip to main content

On 16 September a researcher named Ryan Fahey published a piece called Keys Not Included, which reached the Hacker News front page the following day at 281 points. The short version: several US states cryptographically sign the barcode on the back of a driving licence, none of them published a way to check that signature, and he reconstructed the check anyway from a handful of real cards.

That is a satisfying piece of applied cryptography. It is also the cleanest illustration we have seen this year of something that turns up in nearly every procurement conversation we sit in on: a security feature nobody outside the vendor can verify is, operationally, a security feature that does not exist.

TL;DR

  • Five US states sign the AAMVA barcode on their licences through one card vendor, and none published the signing construction or the public key, so the signature protected nobody.
  • California, through a different vendor, shipped the same idea properly: a W3C Verifiable Credential Barcode, a published key at a stable URL, documentation of exactly what is covered, and an open-source verifier with valid and revoked test cards.
  • California announced the signature in October 2025 and published the documentation in April 2026. For six months the feature was real and uncheckable. “We sign it” and “you can check it” are separate ship dates, and most products never ship the second.
  • Verifying a signature is not verifying a counterparty. The photo is not signed at all, so a genuine barcode copied onto a counterfeit card still passes.
  • We resolved California’s key document ourselves today: it lists six verification methods, and only one of them signs barcodes. Trusting the document rather than the specific key is the same mistake as running cosign verify without --certificate-identity.

What is actually on the back of the card

Every US state licence carries a PDF417 barcode in the AAMVA format. Most of it is plaintext: three-letter element codes and their values, with a header carrying an Issuer Identification Number that says which jurisdiction printed the card. The standard also reserves jurisdiction-specific subfiles, prefixed with Z plus a state letter, for whatever a state wants to add.

Inside those subfiles, in New York, Virginia and North Carolina, sits an Ascii85-encoded blob. Strip the encoding and you get a DER SEQUENCE of two 256-bit integers, which is the canonical wire format of an ECDSA signature over P-256.

The states never documented what is signed, so the signature could not be checked. Fahey worked out the construction: unlike California’s, the signature field is itself covered by the signature. Before signing, the encoder fills the field with the character 0 repeated to the field’s exact length, signs the whole payload including that placeholder, then writes the real signature over the top.

With the message known, ECDSA does the rest. A signature plus its message yields a small set of candidate public keys, and across several signatures from the same signer only the real key appears every time. Three New York cards agreed on one key. Six Virginia samples, fifteen pairs, agreed on one. Two North Carolina cards agreed, which is the minimum it takes.

One correction worth making, because the headline invites the wrong conclusion: these are public keys. Recovering one lets anyone check a signature. It does not let anyone forge one. Fahey then ran the finished verifier against a counterfeit New York card whose barcode was a good clone: same payload length, same subfile directory, same field widths and padding, same card-revision date, and a well-formed 71-byte DER signature in the right field with the right encoding. It failed instantly, because it had been signed with a throwaway key.

California shipped the part that matters

California does not print its own cards either. IDEMIA does, under a twelve-year contract awarded in 2022, with issuance starting in October 2025. Inside California’s ZC subfile is a complete W3C Verifiable Credential Barcode, compressed with CBOR-LD and signed with the ecdsa-xi-2023 cryptosuite. Which AAMVA fields are covered is selected by a bitstring and spelled out in the specification. The credential points at did:web:credentials.dmv.ca.gov, which resolves to a plain JSON document on the DMV’s own domain, containing a P-256 public key anyone can download. California also ships an open-source verifier with real valid and revoked test barcodes.

That is four things, and the signature is only the first of them. A published key at a stable, resolvable address. Documentation of precisely what bytes are covered and in what order. A reference implementation with test vectors for both the passing and the failing case. Ship one without the other three and you have built a seal that looks impressive and confirms nothing.

The part that should bother anyone buying software: IDEMIA produces cards for thirty-one of the fifty-one US jurisdictions, and exactly one of them has a publicly verifiable barcode. The engineering is finished, paid for, and running at the scale of the largest state in the country. The constraint was never technical.

Two different ship dates

California announced the digital signature in a press release on 1 October 2025. The technical overview explaining what signs what, which fields are covered and where the key lives arrived the following April. For roughly six months the cards were in circulation, the signature was real, the announcement was public, and nobody outside the DMV could check anything.

We see that gap constantly, and it is rarely malicious. So when a vendor tells you a thing is signed, the useful question is not whether they sign it. It is: what is the URL of the key, what document describes the signed message, and can you send us a test case that fails? If the answer to the third is uncomfortable, you are six months into someone’s October.

A valid signature is not a verified counterparty

Here is the limit, which deserves printing rather than burying. A valid barcode signature proves the state issued that data. The photograph is not signed, and is not in the barcode at all, so a genuine barcode copied onto a counterfeit card verifies perfectly. Cryptography confirms the provenance of the bytes. It says nothing about the binding between those bytes and the person holding them out. That is the same lesson as verified boot reporting green on a rooted handset: an accurate answer to a narrower question than the one being asked.

Which brings us to the detail we checked ourselves rather than taking from the article. We resolved California’s DID document this morning. It lists six verification methods, and its assertionMethod set contains all six. Only one, #vm-vcb-1, is the barcode-signing key; the others carry labels for other credential types the DMV issues. California’s own documentation names the right one, so the information is all there. But the obvious implementation, the one a developer writes when the deadline is Friday, resolves the DID, walks the key list and accepts the credential if any key verifies. That implementation would accept a signature from an unrelated credential programme as a valid licence.

If that sounds theoretical, it is the exact reason cosign verify in keyless mode refuses to run without --certificate-identity and --certificate-oidc-issuer. Without them you confirm that somebody, somewhere, with a certificate from some issuer, signed your container image. The signature is valid and the answer is useless. The same shape recurs in webhook receivers that verify an HMAC without pinning which tenant’s secret produced it, and in artefact promotion pipelines that check a signature exists without checking whose it is. Verification without a pinned expected signer is an expensive way to write return true.

What to do with this

Inventory every signature your systems verify and write down, per check, which specific key or identity is expected and where that expectation is configured. If the answer for any of them is “whatever the trust store returns”, that is your first fix. Then do the same for signatures your product produces: if a customer wanted to verify your webhook, your export file or your release artefact without asking your support desk, could they? Publish the key, the construction and a failing test vector, or accept that the feature is decorative.

Third, put the verifiability question into procurement, in writing, alongside the usual security questionnaire. “Is it signed” is a yes/no that any vendor passes. “Where is the key published, what is the signed-message construction, and can we run your verifier against a known-bad sample” separates a shipped feature from a slide. Fourth, if you handle identity documents in Europe, note that this stops being an American story soon: under the EU Digital Identity Wallet your business becomes the relying party, and relying parties are the ones who have to get key pinning and trust lists right.

REPTILEHAUS builds and audits identity, signing and verification flows for products across Ireland and the EU, from webhook and artefact verification reviews to relying-party integrations. If your stack checks signatures and you are not certain what each check actually proves, get in touch.

📷 Photo by mk. s on Unsplash