While MIFARE Classic is optimised for reusable smart cards with per-sector authentication, the MIFARE Ultralight family is designed for a different use case: cheap, disposable, or limited-use tags where cost and simplicity matter more than strong security.
MIFARE Ultralight is the foundation of the NFC Forum Type 2 tag specification, and the NTAG21x derivatives are the most popular NFC sticker and wearable tag chips on the market. Understanding this family is essential for any NFC development involving consumer-facing applications.
The Ultralight family has grown considerably over the years. The key members:
| Chip | Memory (user bytes) | Pages | Security | Notes |
|---|---|---|---|---|
| MIFARE Ultralight (MF0ICU1) | 48 bytes | 16 | Lock bytes only | Oldest; NFC Forum Type 2 |
| MIFARE Ultralight C (MF0ICU2) | 48 bytes | 48 | 3DES authentication | Adds crypto auth |
| MIFARE Ultralight EV1 (MF0ULx1) | 48 or 128 bytes | 20 or 41 | Password (32-bit) | Counter, tearing detection |
| NTAG210 | 48 bytes | 16 | Password (32-bit) | Minimal NTAG |
| NTAG212 | 128 bytes | 36 | Password (32-bit) | |
| NTAG213 | 144 bytes | 45 | Password (32-bit) | Most common NFC sticker |
| NTAG215 | 504 bytes | 135 | Password (32-bit) | Used in Amiibo |
| NTAG216 | 888 bytes | 231 | Password (32-bit) | Largest standard NTAG |
| NTAG I2C | 888 bytes / 2 KB | — | Password | Adds I2C interface for dual-interface |
All chips in this family are ISO 14443 Type A compliant. ATQA is 0x0044, SAK is 0x00.
Note that NTAG213/215/216 are the chips you will find in nearly every “NFC sticker” product sold online. NTAG213 is the cheapest and most ubiquitous.
Unlike MIFARE Classic (blocks of 16 bytes), the Ultralight family uses pages of 4 bytes. This is a fundamental difference in addressing.
Page 0: UID byte 0, UID byte 1, UID byte 2, BCC0
Page 1: UID byte 3, UID byte 4, UID byte 5, UID byte 6
Page 2: BCC1, Internal, Lock byte 0, Lock byte 1
Page 3: OTP (One-Time Programmable) byte 0–3
Pages 4–15: User data (48 bytes total)
UID: Ultralight uses a 7-byte UID (ISO 14443 cascade level 2). The UID is spread across pages 0 and 1 with BCC (Block Check Character) bytes interspersed.
BCC0 = UID[0] ⊕ UID[1] ⊕ UID[2] ⊕ 0x88 (cascade tag)
BCC1 = UID[3] ⊕ UID[4] ⊕ UID[5] ⊕ UID[6]
Lock bytes (pages 2, bytes 2–3): 16 bits that, when set to 1, permanently lock individual pages as read-only. Once a lock bit is set it cannot be cleared — the operation is irreversible. Bit mapping:
Lock byte 0 (page 2, byte 2):
bit 7: lock page 7 bit 3: lock page 3
bit 6: lock page 6 bit 2: lock page 2 (OTP)
bit 5: lock page 5 bit 1: block write access to pages 4–9
bit 4: lock page 4 bit 0: block write access to pages 0–3
Lock byte 1 (page 2, byte 3):
bit 7: lock page 15 ...
bit 0: lock page 8
OTP (One-Time Programmable) page (page 3): A 32-bit OTP register. Individual bits can be set from 0 to 1 but never back to 0. Used to mark a tag as “used” in ticketing applications by flipping specific bits on first validation.
User data (pages 4–15): 12 pages × 4 bytes = 48 bytes available for application data.
NTAG213 is the most common chip you will work with. Its 45-page layout:
Page 0: UID byte 0–2, BCC0
Page 1: UID byte 3–6
Page 2: BCC1, Internal, Lock byte 0, Lock byte 1
Page 3: Capability Container (CC) — 4 bytes
Pages 4–39: User data (144 bytes)
Page 40: Dynamic lock bytes (3 bytes) + RFUI
Page 41: CFG 0 (Mirror, Auth0 config)
Page 42: CFG 1 (Access config, NFC_CNT_EN)
Page 43: PWD (4-byte password)
Page 44: PACK (2-byte password acknowledge) + RFUI
The Capability Container is defined by the NFC Forum Type 2 Tag specification and tells an NDEF reader how to use the tag:
Byte 0: Magic number — 0xE1 (NFC Forum magic)
Byte 1: Version — 0x10 (version 1.0)
Byte 2: Size — 0x12 (NTAG213: 18 × 8 = 144 bytes user memory)
Byte 3: Access — 0x00 (read/write) or 0xFF (read-only)
If byte 0 is not 0xE1, most NFC libraries and smartphones will not attempt to read NDEF from the tag.
NTAG21x has an extended lock mechanism. Three lock bytes at page 40 cover user pages 4–39 in groups of 4 pages:
Byte 0 of page 40:
bits 7–4: lock pages 36–39
bits 3–0: lock pages 32–35
Byte 1:
bits 7–4: lock pages 28–31
bits 3–0: lock pages 24–27
Byte 2:
bits 7–4: lock pages 20–23
bits 3–0: lock pages 16–19
CFG 0 (page 41):
Byte 0: MIRROR — enables ASCII mirror of UID/NFC counter into user data
Byte 1: RFUI (reserved)
Byte 2: MIRROR_PAGE — starting page for mirror
Byte 3: AUTH0 — page number from which password protection starts
(0xFF = no password protection)
CFG 1 (page 42):
Byte 0: ACCESS
bit 7: PROT — if 1, write AND read require password; if 0, write only
bit 6: CFGLCK — if 1, configuration pages 41–42 are locked
bit 5: RFUI
bit 4: NFC_CNT_EN — enable NFC counter
bit 3: NFC_CNT_PWD_PROT — counter read requires password
bits 2–0: AUTHLIM (0 = unlimited; 1–7 = max failed auth attempts)
PWD (page 43): 4-byte password, written by the programmer, verified by the tag on PWD_AUTH commands. Factory default is 0x00000000.
PACK (page 44, bytes 0–1): 2-byte password acknowledge. The tag returns this value after successful authentication, allowing the reader to verify it is talking to a genuine tag. Factory default is 0x0000.
NTAG21x supports a simple 32-bit password mechanism:
PWD_AUTH command with the 4-byte passwordThis is not a cryptographic mutual authentication — it is just a PIN check. The password is sent in plaintext over the RF link. An eavesdropper within range can capture the password. For consumer NFC stickers protecting a URL or product identity, this is generally acceptable. For high-value applications it is not.
# Example: authenticate with nfcpy (simplified)
import nfc
def on_connect(tag):
password = b'\x01\x02\x03\x04' # 4-byte password
pack = tag.authenticate(password)
print(f"Authenticated, PACK = {pack.hex()}")
with nfc.ContactlessFrontend('usb') as clf:
clf.connect(rdwr={'on-connect': on_connect})
Ultralight C adds a real cryptographic authentication layer using 3DES (Triple-DES with 112-bit keys) — the same algorithm used in older banking systems. Memory is the same 48 user bytes as the original Ultralight, plus extra pages for the 3DES key material (pages 44–47, 16 bytes total).
The 3DES authentication is a 3-pass mutual authentication:
| Reader decrypts RndB, generates RndA, sends Enc(RndA | RndB’) |
After authentication, read and write commands to protected pages are encrypted. The protection boundary is configured by pages 42–43.
Ultralight C is less common than NTAG21x because 3DES is expensive in silicon (larger chip, higher cost) and because the 48-byte user memory is small. It is used in some single-use transit tickets and event wristbands where a level of authentication is needed without the complexity of DESFire.
NTAG215 has 504 bytes of user memory across 135 pages and is the chip used in Nintendo Amiibo figurines. The Amiibo application uses the full user memory and the password feature, with a specific data structure encoding character ID and user save data. The NTAG215 format and password are well-documented by the reverse engineering community and are used by tools like TagMo to create “homebrew Amiibo” from blank NTAG215 stickers.
This is a useful illustrative example: NTAG21x password protection is sufficient to make casual alteration inconvenient, but with a reader in hand and knowledge of the password structure (or brute force of the 32-bit space), the protection is breakable.
NTAG I2C is a dual-interface chip: it has both an NFC interface (ISO 14443 Type A) and an I2C interface. This allows an embedded microcontroller to write data to the tag over I2C, and an NFC reader to read it contactlessly — or vice versa. It is used in smart packaging where a product’s status (temperature, usage counter) is updated by the product’s own embedded system and readable by a phone.
The Ultralight family uses a small command set (compared to MIFARE Classic):
| Command | Code | Description |
|---|---|---|
| GET_VERSION | 0x60 |
Returns chip version and capability info |
| READ | 0x30 |
Read 4 pages (16 bytes) starting at given page |
| FAST_READ | 0x3A |
Read a range of pages in one command |
| WRITE | 0xA2 |
Write 1 page (4 bytes) |
| COMP_WRITE | 0xA0 |
Compatibility write (for Ultralight compatibility) |
| READ_CNT | 0x39 |
Read NFC counter |
| PWD_AUTH | 0x1B |
Submit password |
| AUTH | 0x1A |
Begin 3DES auth (Ultralight C only) |
| HALT | 0x50 |
Put tag to sleep |
READ returns 4 pages at once (even though you address by page number). Most libraries abstract this and let you read or write individual pages.
NFC stickers (smart posters, product authentication). NTAG213/215/216 stickers are produced for less than $0.10 in volume. A URL, vCard, or Wi-Fi credentials stored as NDEF in the user memory makes the sticker interactive without a battery. Smartphones read these natively.
Event tickets and wristbands. Single-use event wristbands often use Ultralight EV1 or NTAG21x with an OTP bit or counter as a “punch” mechanism. The OTP page is used to mark a ticket as used.
Single-trip transit. Disposable paper transit tickets use Ultralight C or Ultralight EV1. The trip data is stored in user pages; authentication prevents forgery.
Medical device labelling. NTAG21x tags are embedded in medical device packaging to store lot numbers, expiry dates, and provenance information readable by a smartphone during clinical setup.
Smart packaging. NTAG I2C allows a product’s embedded system to update freshness or usage data that the consumer can read with a phone.
| ← Chapter 3: MIFARE Classic | Table of Contents | Chapter 5: NDEF Format → |