NFC physical
certification
2024The core question of this system is how to secure and trace a digital object that has been physicalised — by definition something that can be produced without limit.
Authenticity is supplied by a chip that gives the consumer assurance their object is genuine, and lets them explore its full traceability: who designed it, when it was produced.
Two constraints :
- No companion app — friction kills authentication features
- ~€1 per piece — passive NFC only, no battery, no smart device
How it works, briefly
Customer taps their phone on the object. The chip rewrites its URL on the fly and the phone opens it in the browser:
https://domain.com/verify?p=<PICCData>&e=<EncFileData>&m=<CMAC>
p carries the UID and read counter, encrypted with Key 1.
e is an encrypted user payload. m is a truncated AES-CMAC.
The server decrypts p, derives a session key from Key 1 and the UID, recomputes the CMAC, compares.
The customer sees: a web page that says authenticated. That's it. No install, no scan, no account.
The choice of the chip
NTAG 424 DNA. A passive NFC chip (no power source), but with one feature normal NTAGs don't have: it can sign its own reads.
Inside :
- Two AES-128 keys, never readable from outside
- A read counter that increments on every tap
- An NDEF URL field
- SDM (Secure Dynamic Messaging) — the feature that ties the three above together
Provisioning side
Before a chip can sign anything, it has to be keyed. A blank NTAG 424 ships with factory default keys — anyone with a reader can rewrite it. So between print and packaging, the operator passes each piece over a provisioning bench: a Raspberry Pi connected to a PN532 NFC reader, running a small Flask API. One POST authenticates with the factory keys, rotates both AES keys, enables SDM mirroring (UID + counter + CMAC), and writes the NDEF URL. For the operator it's one action. Behind it, a sequence designed so a failure mid-rotation doesn't brick the chip.
One detail that matters: Key 1 is never the same across chips. It's derived from a master key and the chip's UID. A compromised piece leaks one key, not the batch — and the server can always re-derive the right one from the UID at verify time, so no per-chip secret is stored anywhere.
Trade-offs
- On-chip signing instead of a server lookup: the customer's path doesn't depend on our infrastructure being up. Cost: locked to NTAG 424 (NXP), no second source.
- Off-chain signed payload anchored on-chain for ownership, instead of one mint per piece: no gas at production rate, public verifiability still works.
- Side-channel hardening (LRP) implemented but disabled — ~30% throughput cost on the chip, the threat model doesn't include lab-grade attackers.
What I take from it
Designing the cryptography wasn't the hard part. Making it invisible was. The whole stack — chip choice, provisioning bench, server library — exists so the operator does nothing and the customer does one tap.