NFC (near field communication) is 13.56 MHz radio that works over a few centimetres by magnetic induction. It builds on ISO/IEC 14443 and ISO/IEC 18092, carries data in the NFC Forum's NDEF format, and lets a phone read tags or emulate a contactless card. Short range is a usability property, not a security boundary: a relay can stretch it.
This post goes one level below our relay attacks on keyless entry explainer and sits next to how a card payment terminal is made secure and FIDO2 explained. This one covers the radio and data layers they share, and the physics that decides whether a relay works.
Key takeaways
- NFC runs at 13.56 MHz. ISO/IEC 14443 proximity cards have a typical operating range of 7 to 15 cm according to NIST SP 800-98, and the NFC Forum's certified compliant range is 5 mm, so a phone is designed to be touched, not waved.
- ISO/IEC 14443 covers proximity cards, ISO/IEC 15693 vicinity cards, and ISO/IEC 18092 (also ECMA-340) the NFCIP-1 device protocol.
- A contactless payment is anticollision, then ISO-DEP framing, then ISO/IEC 7816-4 APDUs that select an application and run an EMV kernel that produces a one time cryptogram.
- NDEF is the NFC Forum's container format: records with a type name format, a type, an optional ID and a payload. Tag Types 1 to 5 map it onto different chip families.
- Android has supported host card emulation (HCE) since Android 4.4, alongside secure element emulation. iPhone apps can use HCE in the European Economic Area from iOS 17.4, and Apple's NFC and SE Platform from iOS 18.1 in a list of territories that includes the United States.
- A relay forwards genuine messages, so encryption still verifies. Researchers relayed an ISO/IEC 14443A card over 50 m in 2005. The fixes are distance bounding, user presence, limits and lock state rules, not stronger ciphers.
- Never treat a UID as a secret. Android's HCE guide says emulated cards present a random UID on every tap.
What is NFC, and how does it relate to RFID and the ISO/IEC standards?
Frequency, coupling and range
NFC is a subset of high frequency RFID. A reader drives a coil at 13.56 MHz, which sets up an alternating magnetic field. A passive card or tag has its own coil, harvests power from that field and answers by changing its load on the field (load modulation), which the reader detects as tiny changes in its own coil current. Because the coupling is magnetic and falls off very quickly with distance, the useful range is short. NIST SP 800-98, the 2007 guidelines for securing RFID systems, gives ISO/IEC 14443 proximity cards a typical operating range of 7 to 15 cm and ISO/IEC 15693 vicinity cards a longer range. Gerhard Hancke's 2005 relay paper gives the nominal ranges as up to 10 cm for ISO/IEC 14443 and up to 1 m for ISO/IEC 15693.
The NFC Forum cites a typical range of up to 2 cm and states that its certified compliant range is 5 mm, a test point guaranteeing that certified devices work when touched together.
The nominal range is not the attacker's range. NIST SP 800-98 cites researchers who used a portable, low power device to read an ISO/IEC 14443 card from at least 25 cm, and others who eavesdropped on ISO/IEC 14443 traffic from up to 15 metres with fixed antennas tuned to the frequency. Eavesdropping is easier than reading because the listener does not have to power the card.
Where NFC sits in the RFID family
"RFID" covers several bands: low frequency (around 125 kHz) for animal tags and many older door badges, high frequency (13.56 MHz) for payment, transit, passports and NFC, and UHF for inventory tags read from metres away. A phone only talks at 13.56 MHz, so it cannot see a 125 kHz badge at all.
The standards stack
NFC is a stack of standards, and most security confusion comes from mixing up layers.
| Standard | What it defines | Where you meet it |
|---|---|---|
| ISO/IEC 14443 parts 1 to 4 | Proximity cards: physical characteristics, RF power and signal interface (modulation and coding), initialization and anticollision, and the block transmission protocol | Payment cards, transit cards, passports, office badges, phones in card emulation |
| ISO/IEC 15693 | Vicinity cards at 13.56 MHz with a longer read range | Library books, ski passes, NFC Forum Type 5 tags |
| ISO/IEC 18092 (ECMA-340, NFCIP-1) | Active and passive peer modes at 13.56 MHz, transport protocol, data collision control during initialisation | Phone to phone links and the device side of NFC |
| ISO/IEC 7816-4 | Application Protocol Data Units (APDUs), files, application selection | Everything above ISO-DEP: payment, identity, HCE |
| JIS X 6319-4 | The FeliCa air interface | Transit and payment in Japan, NFC Forum Type 3 tags |
| NFC Forum specifications | Digital Protocol, Analog, Activity, NCI, LLCP, NDEF, RTD, tag Types 1 to 5 | Phone and tag interoperability and certification |
| EMVCo contactless specifications | Entry point, kernels, the EMV Contactless Kernel | Card payments on top of ISO-DEP |
Ecma's entry for ECMA-340 says its 4th edition (June 2024) is fully aligned with ISO/IEC 18092:2023 and defines active and passive modes at 13.56 MHz; earlier editions date from 2002, 2004 and 2013. The ISO/IEC 14443 part structure above follows Hancke's paper and NIST SP 800-98: part 2 for modulation and coding, part 3 for anticollision, part 4 for the transmission protocol. NIST adds that compliant readers must handle both Type A and Type B.
The NFC Forum layer is what phones actually implement. Its Digital Protocol specification sits on top of ISO/IEC 14443, 18092 and JIS X 6319-4; version 2.0 added NFC-V. Type 1 Tag features were removed from Technical Specification Release 2021. NCI defines how the phone's processor talks to the separate NFC controller chip, which does the timing critical radio work.
Bit rates and timing
The NFC Forum's Analog specification covers NFC-A, NFC-B and NFC-F at 106, 212 and 424 kbit/s, and Android's HCE guide says emulated cards advertise only 106 kbit/s. The base rate comes straight from the carrier: 13.56 MHz divided by 128 is about 105.9 kbit/s, so one bit at the base rate lasts about 9.44 microseconds. Keep that number in mind, because it explains why relay attacks are hard to stop with ordinary protocol timeouts.
What are the three NFC modes, and which ones do phones support today?
The NFC Forum defines several operating modes. Three matter for security.
Reader/writer mode
The phone powers a passive tag or card and reads or writes it, as with a smart poster or a passport chip. Android's NFC basics guide says phones usually look for tags when the screen is unlocked and route them through a tag dispatch system that parses NDEF for an interested app.
On iPhone, Apple's Core NFC framework provides reader sessions. NFCNDEFReaderSession reads NDEF messages, and NFCTagReaderSession lets an app talk to protocol specific tags. Apple lists ISO 7816, ISO 15693, FeliCa and MIFARE tags.
Peer to peer mode
Two devices exchange data over ISO/IEC 18092, with the NFC Forum's LLCP (version 1.4 adopted December 2022) as the link layer. On phones it has faded. Android's NfcAdapter reference marks the Android Beam callbacks as deprecated in API level 29 (Android 10) with the note that "this feature is removed", and points to Bluetooth for file sharing. Apple's Core NFC documentation describes reader sessions and card sessions but no third party peer to peer API.
Card emulation mode
The phone acts as a contactless card for an existing terminal, gate or door. The NFC Forum calls it the most common mode today. A secure element chip or an app on the main processor answers the reader (details below).
Mode support at a glance
| Mode | What powers the link | Android today | iPhone today |
|---|---|---|---|
| Reader/writer | Phone powers the tag | Yes, NDEF dispatch plus raw tag technologies | Yes, Core NFC reader sessions |
| Peer to peer | Both devices | Android Beam removed from API level 29 | No third party API in Core NFC |
| Card emulation, secure element | Reader powers the field; the secure element answers | Yes, for wallets and provisioned cards | Apple Pay and, from iOS 18.1, the NFC and SE Platform in listed territories |
| Card emulation, host based | Reader powers the field; an app answers | Yes, since Android 4.4 | CardSession in the EEA from iOS 17.4 |
How does a contactless card transaction work at the protocol level?
Here is the half second between tap and beep for a Type A card and an EMV payment. Lower layers only deliver bytes; security comes from the top.
Step 1: polling and anticollision (ISO/IEC 14443-3)
An idle reader keeps its field on and periodically sends a short request command (REQA, or WUPA to wake a halted card). Any Type A card in the field answers with ATQA, a two byte answer that hints at how its UID is coded. The reader then runs anticollision, resolving the UID bit by bit until exactly one card is singled out. It then sends a select command, and the card answers with SAK, a byte that tells the reader whether the card supports the ISO/IEC 14443-4 protocol.
Timing here is strict. Hancke's paper quotes ISO/IEC 14443-3: the card's response time is (n × 128 + 84) / fc if the reader's last data bit was a 1, and (n × 128 + 20) / fc if it was a 0, with n equal to 9 for REQA and select, where fc is 13.56 MHz. That puts the card's answer on a fixed bit grid about 91 microseconds or 86 microseconds after the reader stops.
Android's HCE guide adds an important detail for emulated cards. During Nfc-A activation the phone presents its UID, and "HCE devices should be assumed to have a random UID", generated fresh on every tap. Readers should not depend on it for authentication or identification.
Step 2: protocol activation (ISO/IEC 14443-4, ISO-DEP)
If SAK says the card speaks ISO/IEC 14443-4, the reader sends RATS (request for answer to select) and the card returns ATS, which carries parameters including the frame size and a Frame Waiting Integer (FWI). Hancke's paper gives the Frame Waiting Time formula as (256 × 16 / fc) × 2^FWI, where FWI runs from 0 (about 300 microseconds) to 14 (about 5 seconds) with a default of 4 (about 4.8 ms). From here on, the link is a half duplex block protocol the NFC Forum calls ISO-DEP. The NFC Forum's Digital Protocol specification added support for larger frames for ISO-DEP to cut transaction time.
Step 3: application selection (ISO/IEC 7816-4 APDUs)
Now the reader and card exchange half duplex APDUs. A command APDU has class, instruction and two parameter bytes plus optional data; a response carries data and a two byte status word, where 90 00 means success.
The first command is normally SELECT by AID, an application identifier of up to 16 bytes. Android's guide notes that payment network AIDs are publicly registered and that new deployments should register their own under ISO/IEC 7816-5. For payments, the reader first selects a directory of payment applications, then the chosen application's AID.
Step 4: the EMV kernel
Once the payment application is selected, the terminal's EMV contactless kernel takes over. EMVCo says EMV contactless chip is defined by the EMV Chip, EMV Contactless and EMV Contactless Kernel specifications, and that a one time use security code is generated for every transaction. In plain terms, the terminal reads the card's data records, sends transaction details (amount, currency, date and an unpredictable number), and the card returns an application cryptogram computed with a key that never leaves the chip. The issuer later verifies that cryptogram, so copying the data from one transaction does not let anyone replay it.
Historically each network had its own kernel; EMVCo's list shows Book C-5 and C-6 at version 2.12, published 6 July 2026. On 5 October 2022 EMVCo published the EMV Contactless Kernel Specification, a single kernel meant to reduce how many kernels terminals carry. Its stated features include a secure channel for privacy and eavesdropping prevention, protection against man in the middle and "mitigation of relay attacks", elliptic curve cryptography for card authentication, and support for biometric and mobile cardholder verification. EMVCo launched a testing process for that kernel on 16 October 2024.
Step 5: verification, limits and completion
The kernel decides whether the cardholder must be verified (a PIN, or on a phone, the device unlock). Transactions under a local contactless limit may need none. The terminal then sends the cryptogram for authorization.
| Step | Layer | Messages | What it proves |
|---|---|---|---|
| 1 | ISO/IEC 14443-3 | REQA/WUPA, ATQA, anticollision, select, SAK | A card is present; which one to talk to |
| 2 | ISO/IEC 14443-4 | RATS, ATS, then I-blocks | The card speaks ISO-DEP; frame size and waiting time |
| 3 | ISO/IEC 7816-4 | SELECT by AID, response with status 90 00 | Which application will answer |
| 4 | EMV kernel | Read records, generate cryptogram | The genuine card key signed this transaction |
| 5 | Kernel and issuer | Cardholder verification decision, authorization | Who may approve, and whether the issuer agrees |
Android's guide suggests limiting a whole exchange to about 1 KB of data, which can usually be moved within 300 ms, so the user only has to hold the phone briefly. That 300 ms budget, against bit times of a few microseconds, is the gap a relay attacker lives in.
What is NDEF, and what do NFC Forum tag Types 1 to 5 mean?
NDEF messages and records
NDEF (NFC Data Exchange Format) is the NFC Forum's lightweight container for data on tags and between devices. An NDEF message is one or more records. Android's NFC basics guide describes the fields of a record: a 3 bit TNF (type name format) that says how to interpret the type, a variable length type, an optional variable length ID, and a variable length payload. Android's tag dispatch system reads the first record to decide which app should handle the tag, and the guide warns developers not to assume the whole payload is in the first record.
The TNF values tell a reader what kind of type name follows:
| TNF | Name | Meaning |
|---|---|---|
| 0x00 | Empty | No type, ID or payload |
| 0x01 | NFC Forum well known type | Type defined by an NFC Forum RTD, such as U (URI) or T (Text) |
| 0x02 | Media type | Type field holds a MIME type, such as text/vcard |
| 0x03 | Absolute URI | Type field holds a URI |
| 0x04 | NFC Forum external type | Organization defined type, such as example.com:badge |
| 0x05 | Unknown | Payload type not known |
| 0x06 | Unchanged | Middle or last chunk of a chunked record |
| 0x07 | Reserved | Not used |
Record type definitions (RTD)
The NFC Forum's Record Type Definition specifications define the well known types. The ones you meet daily:
- URI (type
U). The payload starts with one prefix byte that abbreviates a common scheme, then the rest of the URI. 0x01 meanshttp://www., 0x02https://www., 0x03http://, 0x04https://, and 0x00 means no abbreviation. - Text (type
T). A status byte, a language code, then the text. - Smart Poster (type
Sp). A record whose payload is itself an NDEF message containing a URI record plus optional title text records, an icon, an action and a size. The NFC Forum lists smart posters as a key application level use case. - Signature. Lets a tag carry a signature over its records. Do not assume phones check it.
A worked example: the bytes of one URI record
Here is a single URI record pointing at https://safeguard.sh, decoded byte by byte.
D1 record header: MB=1 ME=1 CF=0 SR=1 IL=0, TNF=0x01 (well known)
01 type length: 1 byte
0D payload length: 13 bytes (short record)
55 type: "U" (URI)
04 URI prefix code: "https://"
73 61 66 65 67 75 61 72 64 2E 73 68 "safeguard.sh"
0xD1 is 1101 0001: message begin and message end are set (one record), short record is set so the length fits in one byte, there is no ID, and the low bits 001 mean a well known type. The payload is 1 prefix byte plus 12 characters, 13 bytes, and the record is 17 bytes.
On a Type 2 tag, the record is wrapped in a TLV block: 03 (NDEF message TLV), 11 (length, 17 in hex), the 17 record bytes, then FE (terminator TLV). That 20 byte block fits easily in even the smallest common tags.
NFC Forum tag Types 1 to 5
A tag type maps NDEF onto a chip family: how readers detect, read and write it.
| NFC Forum type | Air interface | Typical chip family | Notes |
|---|---|---|---|
| Type 1 | NFC-A (ISO/IEC 14443A based) | Early Topaz style tags | Features removed from NFC Forum Technical Specification Release 2021 |
| Type 2 | NFC-A | Low cost memory tags such as MIFARE Ultralight and NTAG class chips | The common sticker and wristband tag; simple page based memory |
| Type 3 | NFC-F (JIS X 6319-4) | FeliCa | Android's Ndef reference gives Sony FeliCa as the example |
| Type 4 | NFC-A or NFC-B with ISO-DEP | Smart card class chips such as MIFARE DESFire | NDEF lives in files selected with ISO/IEC 7816-4 APDUs |
| Type 5 | NFC-V (ISO/IEC 15693) | Vicinity tags | Added to the NFC Forum stack with Digital Protocol 2.0 |
Android's Ndef reference says every NFC Android device must enumerate NDEF on Types 1 to 4 and recommends them for new deployments; its advanced guide lists MifareClassic as optional.
How do host card emulation and secure element emulation differ on Android and iPhone?
Secure element emulation
A secure element is a tamper resistant chip built to keep keys inside. Android's HCE guide explains that the card is provisioned into the secure element (embedded, or in many SIM cards) through an app, and at the terminal the NFC controller routes reader data directly to the secure element. No Android app is involved in the transaction.
Host card emulation on Android
With HCE, the NFC controller forwards reader commands to the host CPU, where an ordinary app answers. Android has supported it since Android 4.4. The details from Android's guide that matter for security:
- Protocols. Android emulates cards based on the NFC Forum ISO-DEP specification (built on ISO/IEC 14443-4) and processes APDUs as defined in ISO/IEC 7816-4. ISO-DEP over Nfc-A is mandatory; Nfc-B is optional.
- Routing by AID. The first APDU is usually SELECT AID. Android resolves the AID to a registered service and forwards APDUs to it until the reader selects a different AID or the link breaks. Android supports a single logical channel.
- Categories. AID groups are either
CATEGORY_PAYMENTorCATEGORY_OTHER. Only one payment AID group can be enabled at once. A payment app can only process a transaction if the user made it the default payment app (the Wallet role holder on Android 15 and later) or if it is in the foreground and callssetPreferredService. - Who can bind. The service must require
android.permission.BIND_NFC_SERVICE, a system permission, so only the OS can bind to it. Android's guide calls this the core security property of HCE: APDUs really come from the NFC controller, and responses only go back to it. - Where the secrets live. The guide says HCE "does not care where the data comes from". Protecting credentials is the developer's job, starting with the app sandbox.
- Lock and screen state. On Android 9 and lower, HCE stops with the screen off and
android:requireDeviceUnlockdecides lock screen use. Android 10 added Secure NFC: while it is on, all card emulators are unavailable with the screen off, and the unlock attribute only applies as before while Secure NFC is off. On Android 15 and higher, a default wallet using Observe Mode overrides these behaviours. - Observe Mode.
NfcAdapterexposessetObserveModeEnabled, so the adapter observes polling frames instead of letting a transaction proceed, andallowOneTransactionto permit one HCE transaction.
Card emulation on iPhone
Apple offers two developer routes, both gated by entitlements, plus Apple Pay itself.
- HCE through
CardSession(EEA). Apple says iOS 17.4 or later includes APIs for HCE payments, car keys, transit, badges, hotel keys and tickets for apps in the European Economic Area, on iPhone XS or later. Apps need an HCE entitlement, must support ISO 14443-4 and ISO 7816-4 commands, and developers commit to standards including PCI DSS and EMVCo. TheCardSessionreference says apps must checkCardSession.isSupportedandCardSession.isEligibleand declare the ISO 7816 identifier prefixes they listen for. - NFC and SE Platform. iOS 18.1 introduced APIs that let apps present contactless cards using the Secure Element, Secure Enclave and Apple servers. It needs an agreement with Apple and an entitlement, in listed territories including the United States, United Kingdom, Canada, Australia and Japan.
- Default app behaviour. Both pages say the default contactless app launches on a double click of the side or Home button, after user authentication if the iPhone is locked.
Side by side
| Property | Secure element emulation | Host card emulation |
|---|---|---|
| Who answers the reader | A separate tamper resistant chip | An app on the main processor |
| Where keys live | Inside the secure element | Wherever the app keeps them; usually short lived keys or tokens |
| Exposure if the phone OS is compromised | Keys stay in the chip; transaction flow may still be abused | Keys and responses are reachable by code running in the app's context |
| Provisioning | Through issuer and platform agreements | Ordinary app distribution plus backend provisioning |
| Android | Embedded SE or SIM, routed by the NFC controller | Since Android 4.4; payment category needs default wallet role or foreground preference |
| iPhone | Apple Pay; NFC and SE Platform from iOS 18.1 in listed territories | CardSession from iOS 17.4 in the EEA |
| Relay exposure | Same as a physical card unless user presence is required | Same; lock state and Observe Mode settings decide |
Neither architecture stops a relay, because a relay never touches the keys.
How do relay attacks and eavesdropping work, and what limits them?
This section covers mechanism and defence only.
Three different threats
- Eavesdropping is passive listening to a legitimate exchange. Encrypting application data, as the EMV Contactless Kernel's secure channel does, is the defence.
- Skimming is an unauthorized reader talking to a card in your pocket. It is limited by range, and a skimmed cryptogram cannot be reused.
- Relaying forwards messages between a real card and a distant real reader. Every cryptographic check passes, because the genuine card computes every answer.
Why cryptography alone cannot stop a relay
Authentication proves the responder holds a key, not where it is. Hancke wrote in 2005 that "application-level measures fail to protect against relay attacks", and argued for solutions based on the physical characteristics of the radio channel.
What the research record shows
| Date | Work | What it showed |
|---|---|---|
| 1993 | Brands and Chaum, "Distance-Bounding Protocols", EUROCRYPT 1993 | Proposed bounding a prover's distance by timing rapid challenge and response bits against the speed of light |
| 2005 | Hancke, "A Practical Relay Attack on ISO 14443 Proximity Cards" | Relayed an ISO/IEC 14443A card over up to 50 m; the relay added 15 to 20 microseconds and the reader still worked |
| 2005 | Hancke and Kuhn, "An RFID Distance Bounding Protocol" (SecureComm 2005) | Proposed a distance bounding protocol over ultra wideband pulses that a simple passive token could implement |
| 2007 | NIST SP 800-98 | Recorded rogue scanning of ISO/IEC 14443 cards at 25 cm or more and eavesdropping at up to 15 m |
| 2010 | Francis, Hancke, Mayes and Markantonakis, IACR ePrint 2010/228 | Showed off the shelf NFC phones could act as relay devices using public APIs, and discussed location based countermeasures |
| 2011 | Issovits and Hutter, IEEE RFID-TA 2011 | Analysed weaknesses of ISO/IEC 14443 regarding relay attacks |
| 2015 | Chothia, Garcia, de Ruiter, van den Breekel and Thompson, "Relay Cost Bounding for Contactless EMV Payments", FC 2015 | Explained why relays against EMV contactless are hard to stop with timing and proposed a relay resistant protocol that fits the EMV contactless specification |
| 2022 | Radu, Chothia, Newton, Boureanu and Chen, "Practical EMV Relay Protection", IEEE S&P 2022 | Showed a transit mode combination on a locked phone could be relayed for payments, showed a proposed countermeasure could be bypassed, and proposed L1RP, a relay resistance protocol at the ISO 14443 level |
| 2022 | EMVCo publishes the EMV Contactless Kernel Specification (5 October) | Lists relay attack mitigation and a secure channel among its features |
The 2015 paper explained why timing EMV is hard: card cryptography takes far longer than communication, so relay delay hides in the noise, and some messages can be cached in advance. The 2022 paper's project page reports that one wallet and card network combination in transit mode could be paid from a locked phone above the contactless limit, and in January 2023 said it was still live; check current guidance rather than that date. The lesson is about design: any mode that removes user presence turns a phone back into a card for relay purposes.
Distance bounding: the physics
A relay always adds distance, and distance costs time. Radio travels at about 3 × 10^8 metres per second, which is about 30 cm per nanosecond. A distance bounding protocol measures the round trip of a challenge and response and refuses to accept a responder whose answer comes back later than light could manage from an allowed distance.
Worked example 1: what ordinary timeouts allow. Take Hancke's anticollision figure of about 86 microseconds as a timing slot. In 86 microseconds, light travels 86 × 10^-6 × 3 × 10^8 = 25,800 metres. A round trip uses that time twice over the relay's length, so a perfectly fast relay could be up to about 12.9 km long and still fit, ignoring processing time. Now take the default ISO-DEP frame waiting time of 4.8 ms: light covers 1,440 km in that time, half of that each way.
Worked example 2: what distance bounding needs. Suppose you want to be sure the card is within 10 cm. The extra round trip a relay of length d adds is 2d / c. For d = 10 cm, that is 0.2 / (3 × 10^8) = 0.67 nanoseconds. One bit at 106 kbit/s lasts about 9.44 microseconds, more than 14,000 times longer. So a reader cannot bound distance at centimetre scale by measuring when an ordinary frame arrives. It needs a dedicated rapid bit exchange with nanosecond resolution and a responder that answers each bit with almost no processing delay, which is why Hancke and Kuhn proposed ultra wideband pulses and why phones and cars now use UWB ranging for secure proximity.
Worked example 3: the relay in the 2005 paper. Hancke's relay added 15 to 20 microseconds, and the reader still worked. A bound with even 1 microsecond of slack would have flagged it. Nothing was measuring.
What actually limits relays in the field
| Control | What it does | Limits |
|---|---|---|
| Relay resistance timing in the payment protocol | The terminal times a short, fresh exchange the card cannot precompute | Coarse timing stops slow relays (for example over the internet) more reliably than fast dedicated hardware |
| Distance bounding over UWB | Measures round trip at nanosecond scale | Needs UWB hardware on both sides; not part of basic NFC |
| Cryptograms with an unpredictable number | Stops replay and cloning of a captured transaction | Does nothing against a live relay |
| Contactless limits and cardholder verification | Caps what a no verification tap can authorize | Transit and offline modes may be exempt; check the issuer's rules |
| User presence on phones | Requires unlock or biometric at the moment of payment | Express or transit modes remove it by design |
| Secure NFC and lock state settings | Turns off card emulation with the screen off or locked | Depends on user settings and wallet choices |
| Issuer risk checks | Flags unusual location, amount or merchant | After the fact; not a protocol guarantee |
| Shielding sleeves and wallets | Blocks the field when the card is not in use | Only works while the card is inside |
For access control the same logic applies: a badge with strong keys cannot be copied by reading, but can still be relayed unless the door adds timing or a second factor.
How does NFC compare with Bluetooth LE, UWB and QR codes?
| Property | NFC | Bluetooth LE | UWB | QR codes |
|---|---|---|---|---|
| Typical working range | A few cm (touch) | Metres to tens of metres | Metres, with centimetre level ranging | Line of sight to a camera |
| Setup latency | Tens to a few hundred ms per tap | Discovery and connection, often hundreds of ms or more | Needs a session, often started over BLE | Camera focus and decode |
| Power for the passive side | Tag is powered by the reader's field | Both sides powered | Both sides powered | Printed; no power |
| Security model | Application layer crypto (EMV, ISO 7816 apps); radio has no built in encryption | Link layer pairing and encryption; application crypto on top | Secure ranging plus application crypto | Whatever the encoded URL or payload does; no channel security |
| Relay resistance | None in the radio; depends on protocol timing and user presence | Weak; signal strength is easily spoofed for proximity | Designed for it: time of flight ranging | A screenshot can be forwarded; relies on dynamic codes and server checks |
| Typical payment use | Card and wallet taps | Rare for point of sale | Emerging for hands free use cases | Merchant or customer presented codes |
| Typical access use | Badges, hotel keys, phone keys | Phone keys with proximity unlock | Hands free car and door entry | Visitor passes |
| Pairing use | Tap to pair handover | Main transport | Precise proximity confirmation | Scan to pair Wi-Fi or devices |
Where proximity is the security property, only time of flight ranging gives a physical guarantee.
Step by step: read a tag, lock it, and audit a badge
Only do this on tags and badges you own or are explicitly authorized to test. Locking a tag is permanent, and testing someone else's access system without written permission may be illegal.
1. Read a tag's NDEF content with a phone
On Android, this Kotlin snippet reads the NDEF message from a tag delivered to your activity:
// In an Activity that received ACTION_NDEF_DISCOVERED or ACTION_TECH_DISCOVERED
val tag: Tag? = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG, Tag::class.java)
val ndef = tag?.let { Ndef.get(it) }
ndef?.use {
it.connect()
val msg = it.ndefMessage // may be null on an empty tag
Log.i("nfc", "type=${it.type} writable=${it.isWritable} " +
"canLock=${it.canMakeReadOnly()} max=${it.maxSize}")
msg?.records?.forEach { r ->
Log.i("nfc", "tnf=${r.tnf} type=${String(r.type)} uri=${r.toUri()}")
}
}
On iPhone, Core NFC's NFCNDEFReaderSession provides the same read through a system scanning sheet, and the app needs the NFC reader session formats entitlement listed in Apple's Core NFC documentation.
2. Read the same tag from a Linux workstation
libnfc is an LGPL licensed, platform independent NFC library from the nfc-tools project. Its project page says it supports ISO14443-A/B, ISO18092 and JIS X 6319-4 modulation and can act as initiator (reader) or target. The latest release tag on its repository is libnfc-1.8.0, published 22 May 2020, so check whether your distribution carries patches on top. nfcpy is a Python library whose tagtool.py example reads and writes NDEF.
# Debian or Ubuntu with a supported USB reader
sudo apt install libnfc-bin
nfc-list # lists the reader and any target in the field
nfc-poll # waits for a target and prints its type details
# nfcpy (Python 3)
python3 -m pip install nfcpy
python3 tagtool.py show -v # from the nfcpy examples; prints NDEF records
nfc-list prints the technology, ATQA, UID and SAK of a Type A target. tagtool.py show prints information about a tag, including NDEF data if present.
3. Parse the bytes yourself
This minimal parser turns a hex dump from your own tag back into records:
URI_PREFIX = {0x00: "", 0x01: "http://www.", 0x02: "https://www.",
0x03: "http://", 0x04: "https://"}
def parse_ndef(data: bytes):
i, records = 0, []
while i < len(data):
hdr = data[i]; i += 1
tnf, sr, il = hdr & 0x07, bool(hdr & 0x10), bool(hdr & 0x08)
tlen = data[i]; i += 1
if sr:
plen = data[i]; i += 1
else:
plen = int.from_bytes(data[i:i+4], "big"); i += 4
idlen = data[i] if il else 0; i += 1 if il else 0
rtype = data[i:i+tlen]; i += tlen
rid = data[i:i+idlen]; i += idlen
payload = data[i:i+plen]; i += plen
rec = {"tnf": tnf, "type": rtype, "id": rid, "payload": payload}
if tnf == 1 and rtype == b"U":
rec["uri"] = URI_PREFIX.get(payload[0], "?") + payload[1:].decode()
records.append(rec)
if hdr & 0x40: # ME, message end
break
return records
print(parse_ndef(bytes.fromhex("D1010D5504736166656775617264 2E7368".replace(" ", ""))))
Running it on the 17 bytes from the worked example prints one record with uri set to https://safeguard.sh.
4. Lock a tag read only (permanent)
Warning: making a tag read only cannot be undone. Before you run any lock step, confirm three things: the tag in the field is the one you mean to lock (check its UID with nfc-list or the log line above), the NDEF content is final (read it back and compare), and no other tag is near the antenna.
On Android, Ndef.makeReadOnly() locks a tag if canMakeReadOnly() returns true:
ndef.use {
it.connect()
check(it.isWritable) { "already read only" }
val expected = "https://safeguard.sh"
val actual = it.ndefMessage?.records?.firstOrNull()?.toUri()?.toString()
check(actual == expected) { "content mismatch: $actual" } // device check step
if (it.canMakeReadOnly()) {
val ok = it.makeReadOnly() // irreversible
Log.i("nfc", "locked=$ok")
}
}
nfcpy's tagtool.py has a protect command that sets read only or password protection on supported tags. Read the nfcpy documentation for your tag type before using it, and run tagtool.py show first to confirm you are pointing at the right tag. Its format command also has a --wipe option that overwrites the data area, which destroys content; treat it with the same check first rule.
Why lock? An unlocked public tag can be repointed to a phishing page by anyone with a phone.
5. Audit what an office access badge exposes
- Find the band. If nothing at 13.56 MHz answers a phone or
nfc-list, it is probably a 125 kHz badge, which typically sends a fixed number and should be replaced. - Record the technology. Note ATQA, SAK and whether the UID changes. ISO-DEP capable badges can run key based authentication; memory only chips cannot.
- Check what the reader trusts. Ask the administrator whether readers authenticate with keys or just read a UID or stored number.
- Check for legacy crypto that public research has broken, and for a migration plan.
- Check relay exposure. Do sensitive doors require a PIN or biometric too?
| Finding | Risk | What to do |
|---|---|---|
| 125 kHz badge with fixed ID | Read and copy from short range | Migrate to authenticated 13.56 MHz or phone credentials |
| 13.56 MHz badge, reader checks UID only | Any device presenting the UID passes | Turn on application level authentication in readers |
| Legacy proprietary crypto | Keys recoverable per public research | Plan migration; restrict sensitive doors to stronger credentials |
| Strong card, no second factor on sensitive doors | Relay possible while the holder is nearby | Add PIN or biometric for high value doors |
| Phone credential with lock state disabled | Relay or misuse from a locked phone | Require unlock for access credentials where the platform allows |
Common mistakes
- Writing URLs to unlocked tags in public places. Anyone can rewrite them. Lock the tag and point it at a redirect you control.
- Assuming short range means secure. NIST records eavesdropping at up to 15 m and Hancke relayed a card over 50 m.
- Using the UID as an identity. UIDs are readable by anyone in range and phones in HCE present random ones. Authenticate with keys.
- Keeping cloneable legacy access cards. Fixed number 125 kHz badges and access systems built on broken card crypto should be on a replacement plan.
- Leaving wallets usable without device unlock. Transit or express modes trade security for speed. Enable them only where needed, and use Secure NFC on Android.
- Auto opening tag URLs. Show the full URL before opening it.
- Parsing NDEF without bounds checks. A hostile tag can claim lengths longer than its data; check every length.
- Treating HCE keys like secure element keys. Long lived secrets in app storage can leak from a compromised phone; prefer short lived tokens and hardware backed keystores.
- Forgetting about the reader side. Terminal and door reader software, and the libraries in it, need patching like any other software.
FAQ
What frequency does NFC use and how far does it reach?
NFC uses 13.56 MHz. NIST SP 800-98 gives ISO/IEC 14443 cards a typical operating range of 7 to 15 cm, and the NFC Forum certifies devices to work at 5 mm. Eavesdroppers with dedicated antennas have reached much further, up to 15 m in research cited by NIST.
What is the difference between ISO/IEC 14443 and ISO/IEC 18092?
ISO/IEC 14443 defines proximity cards and how readers talk to them, in Type A and Type B variants. ISO/IEC 18092 (also published as ECMA-340) defines NFCIP-1, the device to device protocol with active and passive modes, which is compatible with the 14443 Type A and FeliCa air interfaces.
What is an NDEF record?
It is one entry in an NDEF message, the NFC Forum's container for tag data. Each record has a type name format, a type (such as U for URI or T for Text), an optional ID and a payload. Phones read the first record to decide which app handles the tag.
Can someone steal my card details through NFC?
A nearby reader can read some card data, but each EMV transaction uses a one time cryptogram, so captured data cannot be replayed. The bigger risks are a live relay or a small no verification payment.
What is host card emulation?
Host card emulation lets an app on the phone's main processor answer a contactless reader directly, instead of a secure element chip. Android has supported it since Android 4.4. On iPhone, CardSession brings it to apps in the European Economic Area from iOS 17.4.
Does an iPhone support third party NFC payments?
Apple's documentation says yes in two ways: HCE based payments through CardSession for apps in the EEA from iOS 17.4, and the NFC and SE Platform from iOS 18.1 in listed territories including the United States, both behind entitlements and agreements.
What is an NFC relay attack?
Two devices forward messages between a real card and a distant real reader. Encryption does not stop it; timing checks, distance bounding and user approval do.
Does an RFID blocking wallet help?
A shielding sleeve blocks the field while the card is inside. It does nothing once the card is out, or for a phone wallet.
Why software supply chain hygiene still matters here
NFC security lives mostly in silicon, firmware and payment protocols that Safeguard does not analyse, and nothing in Safeguard measures radio timing or inspects card chips. The software around NFC is ordinary software, though: wallet and HCE apps, reader backends, access control servers and tools built on open source libraries such as libnfc and nfcpy all pull dependencies that need tracking and patching.
Fix it without waiting for upstream
Whatever the vulnerability, most of the risk sits in two gaps. The first is the time between a fix being published and that fix actually running in your production builds. The second, and worse, is the time before any fix exists at all, while a maintainer works out a patch and a release schedule. Waiting through both gaps is a habit, not a requirement. Safeguard gives teams three ways to close them.
1. Autonomous remediation: pull requests, not tickets
When a fixed version exists, Safeguard's Griffin models open a tested, policy gated pull request that moves the affected dependency to the safe version. You can run it on one repository or in bulk across every project that carries the vulnerable version. Remediation categories include dependencies, licenses, security posture and findings, and each one is set separately. Reachability analysis ranks the vulnerable code paths your application actually calls first, so the first pull requests you merge are the ones that matter most. Autonomous remediation ships switched off, with every category set to Manual, so your team decides how much runs on its own and what still needs a human approval.
2. Gold Open Source: the safe version in seconds, free
gold.safeguard.sh is free and needs no login. Search any CVE or package to see affected and fixed versions, CVSS, EPSS, CISA KEV status and a recommended safe version, or use the "Am I affected?" checker. The same data is available through a free read API, README status badges and RSS threat feeds.
3. Gold Registry: start from components that are already fixed
Gold Registry provides hardened, drop in replacements for upstream packages and container images. Every Gold artifact is held continuously to zero exploitable critical or high CVEs and a completed license check, with signed build provenance (signed with Safeguard's key and verifiable with cosign, SLSA Build Level 3 as the design target) and a public evidence page you can hand to an auditor. An artifact loses its Gold badge if it regresses. Teams can point their own package directory at the registry so hardened equivalents resolve without changing how developers install anything.
When upstream has no fix yet, or will not ship one, Safeguard first works to get the fix accepted upstream. If the issue is severe or upstream will not move, Safeguard builds a fork, fixes the vulnerability there and publishes a hardened Gold build, so you are not stuck on a maintainer's release schedule. You can also request a hardened, compatibility tested build of a specific package. Ask which packages it covers before you plan around it.
| Your situation | What to use |
|---|---|
| A fixed version exists | Autonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version |
| You need to know today whether you are affected | Gold Open Source lookup and "Am I affected?" checker, free and without login |
| You want vulnerable versions to stop shipping | Safeguard policies and gates in CI |
| Upstream has no fix yet, or will not ship one | A custom Gold request; fork and patch |
| You want to start clean on new projects | Pull hardened components and images from Gold Registry |
One honest limit: when the vulnerable code lives in a vendor appliance, a hosted service or an operating system runtime you do not build yourself, the fix still has to come from that vendor or distribution. The steps above apply to the open source dependencies and container images you build and ship, which is where most teams carry the largest and least tracked share of their exposure.
See how Safeguard would help
None of these demos touch NFC radios, cards or readers; they show the software side.
The first demo is a real Safeguard CLI session. It installs the CLI, opens the interactive terminal and asks it to fix a lodash CVE in a repository. It reads the finding and advisory, asks before any command that changes something, edits package.json to lodash 4.17.21, runs npm install and npm test with approval, prints a summary and pushes nothing. The same flow fits a web backend that provisions HCE tokens or an access control dashboard your team maintains.
Click through it at your own pace, or open it full screen.
The second demo sets up the Safeguard runner on your own machine, approves it with its device code and then scans from the terminal. That suits teams who keep reader integration code, badge enrolment scripts or libnfc based tooling on internal machines and want the scan to run where the code lives.
Click through it at your own pace, or open it full screen.
The third demo is a real Android session: it sends work to a computer running the CLI and approves the command on the phone with Allow once, Allow for turn or Deny. For a developer on an NFC app, a dependency fix can be approved from your phone.
Click through it at your own pace, or open it full screen.
To try it on your own repositories, download Safeguard and follow the CLI documentation.
Quick check
Why doesn't strong encryption between a card and a reader stop a relay attack?
Because a relay forwards the genuine messages unchanged. The real card computes every cryptographic answer, so every check passes. Only a measurement of where the card is, such as distance bounding by round trip time, or a rule that a person must approve the transaction, can tell the reader the card is not actually present.
In the NDEF record D1 01 0D 55 04 followed by "safeguard.sh", what do 0x55 and 0x04 mean?
0x55 is the ASCII letter U, the NFC Forum well known type for a URI record. 0x04 is the URI prefix code for "https://", so the full URI is https://safeguard.sh.
Sources
- NFC Forum: Specifications
- NFC Forum: NFC technology
- Ecma International: ECMA-340, Near Field Communication Interface and Protocol (NFCIP-1)
- NIST SP 800-98, Guidelines for Securing Radio Frequency Identification (RFID) Systems
- EMVCo: EMV Contactless Chip
- EMVCo: EMVCo Publishes EMV Contactless Kernel Specification (5 October 2022)
- Android Developers: Host-based card emulation overview
- Android Developers: NFC basics
- Android Developers: Advanced NFC overview
- Android Developers: Ndef reference
- Android Developers: NfcAdapter reference
- Apple Developer: Core NFC
- Apple Developer: CardSession
- Apple Developer: HCE-based contactless NFC transactions for apps in the European Economic Area
- Apple Developer: NFC and SE Platform for secure contactless transactions
- libnfc on GitHub (nfc-tools)
- libnfc project page
- nfcpy documentation: tagtool.py
- Hancke, A Practical Relay Attack on ISO 14443 Proximity Cards (2005)
- Hancke and Kuhn, An RFID Distance Bounding Protocol (SecureComm 2005)
- Francis, Hancke, Mayes and Markantonakis, Practical NFC Peer-to-Peer Relay Attack using Mobile Phones, IACR ePrint 2010/228
- Chothia et al., Relay Cost Bounding for Contactless EMV Payments, FC 2015 (University of Birmingham)
- Radu et al., Practical EMV Relay Protection, IEEE S&P 2022 (University of Birmingham)
- Practical EMV Relay Protection project page
- Brands and Chaum, Distance-Bounding Protocols, EUROCRYPT 1993 (DOI)
- Issovits and Hutter, Weaknesses of the ISO/IEC 14443 protocol regarding relay attacks, IEEE RFID-TA 2011 (DOI)
Last reviewed: 25 October 2026.