Threat model
What actually defeats an NFC tag check
A signing tag proves one narrow thing: that a particular piece of silicon answered. Nearly every attack that works in practice leaves that proof intact and attacks the distance between it and the conclusion the system draws. This page is written for whoever has to defend the system, which means it is specific about what each attack costs.
Start by writing down what you are actually proving
Most failures in this area are not cryptographic. They are a mismatch between the proposition the cryptography supports and the proposition the product asserts.
A verified Secure Unique NFC message supports exactly this: a chip holding key K computed a message authentication code over counter value N. If you hold K and you have not seen N before, the chip was read, once, after the last time you checked.
Here is what it does not support, listed because every item below is an attack on one of them: that the chip is attached to any particular object; that the reader was near the chip; that the person presenting it is entitled to; that no copy of the message is in flight somewhere else; that the thing you are talking to is a chip at all rather than something emulating one with a key it should not have.
The useful question is never "is this tag genuine". It is "what would have to be true for this message to be valid and the claim to still be false". That list is short and it is enumerable, and working through it is most of the design work.
Copying the link is free. Forging the signature is not.
These two get conflated constantly, in both directions, and the confusion runs both ways: people claim signing tags cannot be copied, and people dismiss them because tags can be copied.
Copying what a tag serves takes a phone. The URL is not secret, there is no authentication before it is served, and writing the same URL onto a blank tag is an ordinary NDEF write. A copy exists within a minute of someone deciding to make one, and it will open the same page on a phone.
What the copy cannot do is produce a valid signature for a counter the server has not seen. It carries whichever counter and signature were captured, so the second time it is presented the counter has already been recorded and the check fails. It fails on the server, not on the phone, and only if the server is actually checking.
Forging a fresh signature means recovering the key. For a 128-bit AES key held in a chip that never emits it, there is no shortcut from the outside, and the signature itself is truncated to 64 bits, so blind guessing succeeds with probability 2-64 per attempt. The realistic routes to the key are the backend that holds the other copy, and configuration mistakes on the tag. Both appear further down this page.
Transplantation: the attack that works
Move a genuine tag onto a different object. Every signature stays valid. Every counter advances normally. Nothing in the protocol has anything to say about it.
This is the attack to design against first, because it costs nothing, requires no equipment, leaves no cryptographic trace, and defeats the entire scheme at the point where the scheme meets the physical world. A system that authenticates tags and reports on objects has simply assumed the two are the same thing.
Chip vendors offer a partial answer. The NTAG 213 TT detects "the status of a tag tamper
wire during the startup", and "in case of an open detection wire, the NTAG 213 TT permanently
stores this event".[18] The NTAG 424 DNA TagTamper does the same and keeps two
values: a permanent status and a current one, ASCII C for closed, O
for opened and I for not yet enabled. Both can be mirrored into the message
alongside the counter and the signature, so the tamper state is covered by the same signature,
and retrieval can be gated behind its own application key.[19] The distinction
between the two values is useful: the current status says whether the wire is broken now, the
permanent status says whether it was ever broken.
Understand precisely what that buys. It detects that a loop was broken, assuming the loop was routed so that removing the tag has to break it. It does not prove the tag is on the right object, it does not detect a tag that was removed carefully enough or was never properly attached, and the permanent status cannot be cleared, which means a false trigger during assembly or shipping produces a tag that reports tampering for the rest of its life. The loop is a construction problem dressed as a chip feature, and most of the engineering is in the inlay and the adhesive rather than the silicon.
Relay: cryptography cannot fix it, and it is cheap
Two radios and a link between them put a tag that is somewhere else in front of your reader. The signature is genuine because a genuine tag computed it.
The reference demonstration is twenty years old. In a 2005 project report Hancke built a proxy that impersonates a card to the reader and a mole that impersonates a reader to the card, linked by a pair of UHF radios. He reports relaying ISO/IEC 14443 transactions "up to a distance of 50 m", notes that "though our system introduced a delay of 15 to 20 microseconds, the reader still functioned normally", and puts the cost of the whole system "well under £100", most of it an off-the-shelf reader module.[1]
Smartphones removed the hardware step. Francis, Hancke, Mayes and Markantonakis demonstrated a relay built from applications on the attackers' own phones, needing no access to secure memory, no code signing, and only publicly available APIs.[2] The current tooling is NFCGate, from TU Darmstadt, which relays over a plain TCP connection between two Android phones. Its own documentation reports the result most clearly: "we successfully read a card in Hamburg with a reader in Darmstadt".[3]
Why your signature scheme cannot help
Hancke and Kuhn state the reason in the paper that proposed the standard mitigation: "Relay attacks cannot easily be prevented by cryptographic protocols that operate at the application layer of an RFID protocol stack. At this layer, information about the arrival times of messages has already been blurred substantially by the many synchronization, collision avoidance, demodulation, symbol detection, error detection and retransmission mechanisms that are implemented in the lower layers. The only effective defense are distance bounding or secure positioning protocols that are tightly integrated into the physical layer."[4]
Neither ISO/IEC 14443 nor any NFC Forum specification provides such a mechanism. Proximity checking exists only as vendor additions layered on top: NXP's proximity check on MIFARE Plus EV1 and DESFire EV2, and the relay resistance protocol in the EMV contactless kernel.
And the vendor answer has limits worth knowing
Kuhn measured the deployed MIFARE Plus EV1 proximity check and found that running a distance-bounding exchange on top of ISO/IEC 14443-4 and ISO/IEC 7816-4 APDU framing destroys its resolution. His figures: a challenge packet of 0.94 ms, a response packet of 0.52 ms, an intra-packet gap of "1.7 ms promised, 1.6 ms actual", leaving "0.1 to 0.2 ms slack" and therefore "15 km distance uncertainty".[5] A check that bounds the card to within a city is still useful against an intercontinental relay and useless against one in the next room.
The attackers agree about where the line is. NFCGate's documentation states that it "only works with readers which do not implement additional security measures", that timing the card's response is the measure that stops it, and that "the network transmission adds a noticeable delay to any transaction, so any secure reader will not accept our proxied replies".[3]
What to do about relay, honestly. Nothing at your layer prevents it. What you can do is decide whether it matters for your threat model, bound the value of a single verification, and notice the statistical signatures: a tag verifying from a plausible-looking phone in one country while its object is in another, or two verifications of the same tag minutes apart and continents apart. None of that is proof. All of it is better than asserting the tag was present.
The originality signature is not freshness, and the vendor says so
Every NXP tag family discussed here carries a static ECDSA signature over its identifier, written at manufacture. It is routinely mistaken for an anti-cloning measure.
On the NTAG 21x family it is a 32-byte signature on curve secp128r1, read with
READ_SIG, and "programmed at chip production and cannot be changed
afterwards".[6] On the NTAG 424 DNA it is 56 bytes on secp224r1, and the
Read_Sig command is "freely available. There is no authentication
required".[7] The verification public key is printed in full in NXP's own public
application note.[8]
That combination is the whole problem. The value is fixed, it is a function only of the identifier, anyone can read it, and anyone can verify it. It carries no freshness whatsoever, so an attacker who can emulate both the identifier and the signature passes the check. NXP states the scope plainly in the data sheet: "The purpose of originality check signature is to protect from mass copying of non NXP originated ICs. The purpose of originality check signature is not to completely prevent HW copy or emulation of individual ICs."[7]
This is not theoretical. The Proxmark3 project documents writable-signature tags where the
signature sits in configuration pages F8h to FFh, with a helper
script to "set UID, set signature", an example that writes a 32-byte signature, and the
instruction to "verify with hf mfu info and look for Signature
verification: successful".[9]
Use the originality signature for what it is: a cheap filter against bulk counterfeit silicon, checkable offline. Do not use it as evidence about an individual tag, and do not present it to a user as proof of anything.
The identifier is an addressing field, not a credential
It is readable by anyone, it is not always unique, and devices that emit an arbitrary one have existed for fifteen years.
NXP's own application note on the subject is unambiguous about what the field is for. The identifier sizes are "defined in ISO/IEC 14443-3 as they are used during the anti-collision and selection procedure", and "in some case the UID is even not unique". For one documented class of 4-byte identifiers, "the same UID might be used for several PICCs, so that contactless systems cannot rely on the uniqueness of such a PICC identifier".[10]
Emulation closed the question in 2010. The Chameleon, by Kasper, von Maurich, Oswald and Paar, enables "the creation of exact clones of such cards, including the UID" and "can be built for less than $25". The paper is explicit that this overturned the assumption systems were relying on: identifiers were treated as trustworthy because "there are no cards available on the market where the UID can be altered".[11] There are now, and general-purpose tooling emulates arbitrary identifiers as a standard feature.
The practical consequence for a verifying backend: look the tag up by its identifier, then decide nothing on that basis. The identifier tells you which key to try. The signature is the only thing that tells you anything.
The attack on the user, not the tag
The cheapest attack does not involve a signature at all. It involves a tag that never offers one, pointed somewhere that always says yes.
A blank tag costs a few cents and can hold any URL. Point it at a domain that resembles yours, serve a page that looks like a successful verification, and a user who has been taught that tapping produces a green tick will get one. No cryptography was attacked. The user has no way to distinguish the two taps, because the thing they are checking is a web page and the attacker wrote it.
This class of problem is old enough to have a CVE. In the Nokia 6131's Smart Poster handling, the implementation "does not properly display the URI record when the Title record contains a certain combination of space, CR and dot characters, which allows remote attackers to trick a user into loading an arbitrary URI via a crafted NDEF tag", demonstrated with a malicious web address, a premium-rate telephone number and a ringtone purchase.[12]
What the operating system shows the user is changing
Android's documented design has been to not ask. "When an Android-powered device discovers an
NFC tag, the desired behavior is to have the most appropriate activity handle the intent
without asking the user what application to use", on the reasoning that a chooser would make
the user move the phone and break the connection.[13] That is being walked back.
Android 16 routes tags carrying http and https links to ACTION_VIEW instead of
ACTION_NDEF_DISCOVERED, and "beginning with Android 17, scanning such a tag
surfaces an 'open link' notification, requiring explicit user interaction to trigger the
ACTION_VIEW intent".[13]
We could not establish what iOS shows the user before opening a tapped link, and in particular whether the hostname is visible, from any source we were able to read. Treat that as unknown rather than assuming either answer.
The design consequence. Any verification whose result the user reads off a web page is only as trustworthy as the user's ability to check the domain, which is to say not very. If the decision matters, it should be made by something that already knows which key to expect, in an application or a backend, not inferred by a human from a page layout.
The key on your side is the softest target
The chip will not give up its copy. The question is how many tags one compromise of your copy is worth.
A symmetric scheme means the verifier holds the same secret. If one key covers the whole fleet, then one compromised verification service, one leaked configuration file or one backup in the wrong bucket produces the ability to forge a valid message for every tag ever issued, indefinitely, with no way to tell forged messages from genuine ones after the fact.
The standard mitigation is key diversification: derive each tag's key from a master key and something unique to that tag, and never store the master key where verification happens. NXP documents a CMAC-based construction for this and states the goal in one sentence: "if one key is broken somehow (maybe from the terminal). The vulnerability is limited to that key on that card rather than the whole system being affected."[14]
There is a trap here specific to Secure Unique NFC. If you encrypt the identifier and counter so they do not appear in the URL, your verifier needs the decryption key before it knows which tag it is talking to, so that key cannot be diversified per tag. NXP says so directly: in that configuration the meta-read key "shall not be UID diversified and high attention on secure storage on system level of this key is required".[15] Privacy for the identifier is bought with a fleet-wide key. Use different application keys for the identifier encryption and the signature so that the fleet-wide one cannot also forge.
What breaks in current parts is configuration, not the cipher
The famous DESFire break is real, is often cited at the wrong chips, and was not an attack on AES.
In 2011 Oswald and Paar presented a power-analysis attack on the MIFARE DESFire MF3ICD40, a part introduced around 2002. Their own figures: "full key-recovery with approximately 250k traces (approximately 7 hours)" using "low-cost equipment, approximately 2500 USD". The chip they attacked used "3DES with a 112-bit key for authentication and data encryption", and their remediation slide reads "DESFire MF3ICD40 replaced by DESFire EV1".[16] This was a successful side-channel attack on a two-decade-old triple-DES engine. It is not a result about AES and it is not a result about any part discussed on this site.
We looked for a published side-channel, fault or cryptanalytic attack recovering an AES key from the NTAG 424 DNA or from MIFARE DESFire EV2 or EV3, and did not find one. That is a search result, not a proof, and it is the kind of statement that can stop being true without notice.
What does currently break in the same generation is protocol handling and configuration. A 2026 preprint reports reducing a two-key triple-DES keyspace "from 2112 to 228 or less in certain real-world deployments" using relay-based interception and partial key overwrites, optionally combined with tearing, and separately reports that on two chips in the NTAG DNA line the absence of integrity checks on commands yields "an unauthenticated ciphertext oracle that facilitates key recovery".[17]
Two caveats that matter, because this paper gets cited loosely. The parts it analyses are the MIFARE Ultralight C, MIFARE Ultralight AES, NTAG 223 DNA and NTAG 224 DNA, plus counterfeit Ultralight C clones. It does not analyse the NTAG 424 DNA, which it never mentions, and it does not analyse DESFire. And it is a preprint, not peer-reviewed work.[17]
The pattern across all of it. The ciphers hold. What fails is default keys left in place, settings left changeable, commands whose integrity nothing covers, counters the backend does not actually track, and tags that can be torn mid-write. All of those are provisioning and verification decisions, which means they are yours.
A defender's list
Nothing here is novel. It is the set of decisions that the attacks above actually reach, written in the order they tend to be got wrong.
- Require the proof, and refuse without it. A request with no signature parameters is not an unverified tag, it is a failed verification. Treat a missing proof and a bad proof identically, and return the same answer for a malformed URL, an unknown tag and a bad signature, so nothing tells an attacker which half of a guess was right.
- Record the highest counter per tag, and write it before you answer. The counter is the only freshness in the scheme. Accepting a counter equal to the last one seen turns a captured URL into a reusable token. Allow repeats within a single read session, because the chip does not increment on consecutive reads of the same file, and reject anything that does not move forward across sessions.
- Diversify the signing key per tag. Then a compromise is one tag, not the fleet. Keep the master key out of the verification path entirely.
- Strip the proof from the URL before anything logs it. Signature and counter in the address bar reach browser history, referrer headers and every analytics script on the page. A counter and signature in an access log are a replayable token sitting in a file that is backed up.
- Never decide anything from the identifier. Use it to select a key. Nothing else.
- Lock the tag properly, and know what that forecloses. Rotate every default key, freeze the file settings, and accept that this is irreversible. The irreversible decisions are enumerated here.
- Rate-limit verification per tag and per source. The chip does nothing to slow down guessing. Your endpoint is the only thing that can.
- Treat a failed check as unknown, not as counterfeit. Offline phones, dead backends and worn tags all produce failures. A system that accuses on a failure will accuse the innocent, repeatedly and in public.
- Say what the tap proved, not what you would like it to mean. "This chip was read just now" is defensible. "This item is genuine" is not, and the gap between them is where every attack on this page lives.
Sources
All documents below were retrieved and read on 2026-10-24. Where a source is a project report, a preprint or an undated lecture deck rather than peer-reviewed work, that is stated, because it changes how much weight it carries.
- G. P. Hancke, A Practical Relay Attack on ISO 14443 Proximity Cards, University of Cambridge Computer Laboratory. Note the footnote on its first page: "Project report, posted January 2005." It has no conference or journal venue and should be cited as an unpublished report. The 50 m range, the 15 to 20 microsecond delay and the cost figure are in sections 5 and 6.
- L. Francis, G. Hancke, K. Mayes and K. Markantonakis, Practical NFC Peer-to-Peer Relay Attack using Mobile Phones, IACR Cryptology ePrint Archive 2010/228; published at RFIDSec 2010, LNCS 6370, pages 35 to 49.
- S. Klee, A. Roussos, M. Maass and M. Hollick, NFCGate, Secure Mobile Networking Lab, TU Darmstadt; presented at USENIX WOOT 2020, preprint arXiv:2008.03913. The Hamburg to Darmstadt result and the distance-bounding caveat are both in the project documentation.
- G. P. Hancke and M. G. Kuhn, An RFID Distance Bounding Protocol, Proceedings of IEEE/Create-Net SecureComm 2005, Athens, 5 to 9 September 2005, pages 67 to 73. The quoted passage is in section 1. This paper proposes a protocol; it does not demonstrate a relay.
- M. G. Kuhn, Distance-bounding protocols, lecture slides. Undated and not peer-reviewed; the content postdates February 2016. The proximity-check timing measurements and the 15 km figure are on the "MIFARE Proximity Check" slide.
- NXP, NTAG213/215/216 product data sheet, Rev. 3.2, 2 June 2015. Section 8.9 for the secp128r1 originality signature, section 10.8 for
READ_SIG. - NXP, NTAG 424 DNA, NT4H2421Gx product data sheet, Rev. 3.0, 31 January 2019. Section 10.10.1 for the
Read_Sigscope statement and the absence of authentication, and for curve secp224r1. - NXP, AN12196, NTAG 424 DNA and NTAG 424 DNA TagTamper features and hints, Rev. 2.0, 4 March 2025. Section 7.2 prints the originality verification public key in full.
- RfidResearchGroup, Notes on Magic Cards, aka UID changeable, Proxmark3 project documentation. See the MIFARE Ultralight USCUID-UL section for the signature configuration pages and the helper script that writes them.
- NXP, AN10927, MIFARE product and handling of UIDs, Rev. 4.1, 5 July 2018. Section 2.1 for the identifier's role in anti-collision and selection, and section 2.1.2 for fixed but non-unique identifiers.
- T. Kasper, I. von Maurich, D. Oswald and C. Paar, Chameleon: A Versatile Emulator for Contactless Smartcards, ICISC 2010, pages 189 to 206. The quoted passages are in the abstract and section 1.
- NIST National Vulnerability Database, CVE-2008-5825, published 2 January 2009. The quoted description is the NVD record itself, retrieved from the NVD API.
- Google, NFC basics, Android developer documentation, sections on the tag dispatch system and on behaviour changes in Android 16 and 17.
- NXP, AN10922, Symmetric key diversifications, Rev. 2.2, 2 July 2019. The quoted sentence is in section 1 and is ungrammatical in the original; it is reproduced as written.
- NXP, AN12196, section 3.4.2. See source 8.
- D. Oswald and C. Paar, Breaking Mifare DESFire MF3ICD40: Power Analysis and Templates in the Real World, CHES 2011 presentation slides. The paper appeared in CHES 2011, LNCS, pages 207 to 222. Figures quoted are from the management summary and target description slides.
- N. Nye, P. Teuwen, T. Messmer, S. Mauch, S. Clark, Z. Li, Z. Weiss and L. Voeltner, BREAKMEIFYOUCAN: Exploiting Keyspace Reduction and Relay Attacks in 3DES and AES-protected NFC Technologies, IACR Cryptology ePrint Archive 2026/100, received 21 January 2026, latest revision 28 August 2026. Listed as a preprint with no peer-reviewed venue.
- NXP, NTAG 213 TT product data sheet, Rev. 1.1, 28 March 2017, sections 1 and 8.8. NXP marks this revision an objective data sheet, meaning the specification was not yet final, and the plain document URL now returns a 404.
- NXP, NTAG 424 DNA TagTamper, NT4H2421Tx product data sheet, Rev. 3.0, 31 January 2019. Section 8.2.4.5 for
TTStatusKey, section 9.3 for mirroring the status into the signed message, section 10.2 for the permanent and current status values.