EdgeNFC
How it works
An EdgeNFC tag is not a serial number printed on a chip. It is a small piece of hardware that holds a secret it never reveals, and uses that secret to sign a different message every time somebody taps it.
The short version. You write a key to the tag once. After that, each tap produces a fresh code, and a verifier re-derives the key and checks the signature and the counter. Nothing about that can be photographed or copied.
The loop
You provision the tag once. Every tap after that is a fresh cryptographic proof your customer — and your server — can trust.
The free Kotlin app writes a unique diversified key + SUN URL to the NTAG 424.
A phone tap opens the URL — carrying a different code every single time.
A Cloudflare Worker re-derives the key, checks the CMAC + counter — at the edge, near your customer, typically in well under a second.
Genuine ✓ — or rejected if it's forged, replayed, or unknown. No ambiguity.
Step 1 · in detail
Provisioning happens once, over NFC, from an Android phone. It writes two things: a key the chip will keep, and a URL template the chip will fill in.
Your System Master Key never goes on a tag. Instead the app derives a per-tag key from the master key and the chip's own UID using AN10922 AES-128 diversification, and writes that. Physically tearing a tag down yields one tag's key — it does not yield the master, and it does not yield any other tag.
The tag is configured for SDM (Secure Dynamic Messaging) and stores a URL with mirror placeholders. On every read the chip fills those placeholders in with live values — so the NDEF record on the tag is not a fixed string, it is a template the hardware finishes at tap time.
A half-provisioned tag is worse than a blank one, so the app reads the tag back and verifies what it wrote before marking the tag DONE. An aborted session leaves a tag that can be re-run, not a brick.
Hosted, it is stored envelope-encrypted and decrypted only transiently at verify time. Self-hosted, it is shown to you once at creation and never persisted by us at all. See the security model.
Step 2 · in detail
A tap opens an ordinary HTTPS URL. What makes it unforgeable is what the chip appends to it, and the fact that those values change on every single read.
The chip keeps a read counter (SDMReadCtr) and increments it on every read. It is included in the signed message, so a captured URL carries a counter value that has already been used — and can be rejected on that basis alone.
The chip computes an AES-CMAC over the SDM message with a session key derived from its own diversified key. Producing a valid code for a counter value you have never seen requires the key, and the key never crosses the air interface.
In the recommended mode, the tag's UID and counter are AES-encrypted into a single picc_data parameter rather than mirrored in the clear, so the URL a passer-by can read does not identify the tag.
Because the payload is a URL, any modern phone can complete the loop — the tap opens a web page and the verdict renders there. The provisioning app is for you, not for the person checking the product.
Step 3 · in detail
Verification is a pure function of the tap and the key. It runs at the edge, on the same Rust/WASM core whether we host it or you do.
Pull the parameters out of the URL. Anything malformed is rejected here, before a key is touched.
Recover the tag's UID (decrypting picc_data in encrypted mode) and re-derive that tag's key from your master key with AN10922 — the same derivation the provisioning app ran.
Derive the SDM session MAC key, recompute the CMAC over the message, and compare it to the one in the URL in constant time, so the comparison itself leaks nothing.
A valid signature is not enough: the counter must be higher than the last one we saw for this tag. A perfectly valid URL, replayed, fails here.
Want to watch the failure rather than read about it? Forge a tap in the live demo — it runs in your browser, no signup.
Where it runs
The verification core is one Rust library compiled to WebAssembly. Hosted and self-hosted deployments run the identical build, so two verdicts on the same tap cannot disagree.
We run the core on Cloudflare's edge network and hold your master key envelope-encrypted. You get the dashboard, the counter state, and analytics without running anything. Every tier includes unlimited verifications.
The $749 perpetual Edge License hands you the same core to run on your own servers or your own Workers. Verification needs no callback to us, so it works on a network that has never seen the internet.
Straight answers
Not always. Some Android phones and versions have a known platform quirk where tapping an NTAG 424 DNA tag doesn't reliably hand the link off to a browser from the home screen or lock screen. It's outside our control, and it varies by device. The reliable workaround is to open the EdgeNFC app and scan the tag from there — same read, same verdict.
No. EdgeNFC is software. You buy blank NTAG 424 DNA tags from a specialist supplier — see where to buy tags — and provision them with our free app.
No. Only the NTAG 424 DNA family implements SDM/SUN with a CMAC and a read counter. Cheaper chips can store a URL, but they cannot sign anything, so there is nothing to verify.
It proves the tag is genuine and has not been replayed. Binding that proof to a physical item is a question of how the tag is attached — a tamper-evident construction, a tag embedded at manufacture. We can prove the tag; the attachment is your design decision.
Next
The demo lets you tamper with a real SUN URL and watch verification refuse it. The security page is the developer-grade version of this page.