The previous chapters covered MIFARE Classic (with its known cryptographic weaknesses) and MIFARE Ultralight (with simple password protection). For applications that genuinely require strong security — financial transactions, high-assurance access control, government ID — a different class of NFC technology is needed.
This chapter gives a concise overview of the secure NFC landscape: MIFARE DESFire, Java Card / JCOP, and related technologies. It is intentionally brief because open-source tooling for these platforms is limited, and deep engagement with them typically requires proprietary SDKs or hardware security modules.
As discussed in Chapter 3, MIFARE Classic’s CRYPTO1 cipher can be defeated in seconds with freely available software. Any application where the consequences of a cloned or manipulated card are serious — financial loss, physical security bypass, identity fraud — cannot rely on MIFARE Classic.
The fundamental problems are:
MIFARE DESFire is NXP’s answer to these shortcomings. It was introduced in 2002 and has gone through three major revisions: EV1 (2007), EV2 (2012), and EV3 (2021).
Instead of sectors, DESFire organises data in a hierarchical model:
Card
└── PICC Master Key (card-level key)
├── Application 1 (AID: 3 bytes)
│ ├── Application Master Key
│ ├── File 1 (Standard Data, Backup Data, Value, Record...)
│ ├── File 2
│ └── ...
└── Application 2 (AID: 3 bytes)
├── Application Master Key
└── ...
Each Application is identified by a 3-byte Application Identifier (AID). An application can have up to 16 keys (numbered 0–15) and up to 32 files. Key 0 of an application is its Application Master Key and controls application-level administration.
This isolation means that a transit application and a payment application can coexist on the same card without either being able to access the other’s data — even if one is completely compromised.
DESFire supports five file types:
| Type | Use |
|---|---|
| Standard Data File | Fixed-size raw byte storage |
| Backup Data File | Standard with atomic write-backup for data integrity |
| Value File | 32-bit signed integer with increment/decrement |
| Linear Record File | Append-only record log |
| Cyclic Record File | Fixed-size circular log |
| Variant | Algorithms |
|---|---|
| DESFire (original) | 3DES (Triple-DES) |
| DESFire EV1 | 3DES, AES-128 |
| DESFire EV2 | 3DES, AES-128 + Proximity Check (relay attack prevention) |
| DESFire EV3 | AES-128 + Transaction MAC, SUN (Secure Unique NFC) message |
EV3’s SUN (Secure Unique NFC) message is particularly interesting: the tag can embed a cryptographically authenticated counter value directly in a URL it broadcasts as NDEF, allowing a server to verify the tag is genuine and has not been replayed — without any backend infrastructure in the reader.
DESFire uses a 3-pass mutual authentication:
| Reader decrypts RndB, generates RndA, sends Enc(RndA | RndB’) (RndB rotated 1 byte) |
After authentication, all subsequent communication is secured with session keys derived from RndA and RndB.
Every file has an access rights byte encoding four 4-bit permission fields:
Bits 15–12: Read access key number (0–13: key required; 14: free; 15: never)
Bits 11–8: Write access key number
Bits 7–4: Read+Write access key number
Bits 3–0: Change access key number
This granular per-file, per-operation access control is far more flexible than MIFARE Classic’s per-sector Key A / Key B model.
MIFARE DESFire is well-documented in NXP’s application notes (AN10833, AN12343, etc.), and the command set is fully specified. The authentication protocol is not secret. So why is tooling limited compared to MIFARE Classic?
No proprietary cipher to reverse-engineer. MIFARE Classic attracted massive security research because CRYPTO1 was secret and broken. DESFire uses AES-128 and 3DES — standard ciphers with no known weaknesses. There is no shortcut to break the auth.
SAM (Secure Access Module) requirements. High-security deployments store the master keys in a SAM — a tamper-resistant hardware module that never exposes keys in plaintext, only performs crypto operations internally. Open-source tools cannot easily interact with SAMs.
Proprietary SDK ecosystem. NXP provides the NXP MIFARE SDK and the NXP TagWriter SDK for production applications. These are closed-source. Open-source implementations exist but are incomplete.
What open tooling exists:
libfreefare (C library on top of libnfc) has partial DESFire support — enough to authenticate, list applications, and read/write standard data files with AES or 3DES keys. It does not support all EV2/EV3 features.IsoDep technology class gives raw APDU access to any ISO 14443-4 tag including DESFire. A Java/Kotlin application can implement the full DESFire protocol on top of this.Java Card is an open standard (now maintained by Oracle) for running Java programs on smart card chips. JCOP (Java Card Open Platform) is NXP’s Java Card implementation, found in contactless payment cards, SIM cards, and high-end access cards.
A Java Card chip runs a Java Card Virtual Machine (JCVM) and can host multiple independently developed applets (analogous to DESFire applications). Applets are installed post-manufacture and communicate via APDU (ISO 7816) commands.
Card OS (JCOP)
├── GlobalPlatform (card management)
│ ├── Card Manager (install, delete, select applets)
│ └── Security Domains
├── EMV Payment Applet
├── Access Control Applet
└── NDEF Applet (optional)
Each applet has a unique AID (Application Identifier, 5–16 bytes). A reader selects an applet by sending SELECT FILE (ISO 7816) with the AID, then exchanges APDUs with it.
Java Card provides strong isolation between applets through the Java Card Firewall — applets cannot access each other’s objects unless explicitly shared via a shareable interface. The on-card JVM enforces type safety and prevents pointer-based attacks that would be possible in C.
GlobalPlatform defines a secure channel protocol (SCP02, SCP03) for applet installation and management, using session keys derived from a card master secret held in the issuer’s HSM.
The contactless payment chip in your bank card is a JCOP card running an EMV payment applet. From an NFC protocol perspective:
The reader (payment terminal) selects the payment applet, runs a cryptographic transaction protocol that generates a transaction-specific cryptogram, and submits it to the payment network for authorisation. The card never transmits its key — only derived cryptograms.
MIFARE Plus is NXP’s migration path from MIFARE Classic — designed for transit operators who need to upgrade security without immediately replacing all their readers. A MIFARE Plus card can operate in “Classic compatibility mode” (SL1 — Security Level 1, using CRYPTO1) or in full AES mode (SL3). The card starts in SL1 and can be permanently upgraded to SL3 by the card issuer using a secure upgrade command.
MIFARE Plus is relevant for transit modernisation but rarely encountered in hobbyist or developer contexts.
| Use case | Recommended chip |
|---|---|
| NFC URL sticker, low-cost tag | NTAG213 |
| Single-use transit ticket | Ultralight EV1 / C |
| Legacy building access (cost-constrained) | MIFARE Classic (accepting the risk) |
| New building access system | DESFire EV2/EV3 |
| Public transit (new deployment) | DESFire EV2/EV3 or MIFARE Plus SL3 |
| Contactless payment | Java Card / JCOP with EMV applet |
| Multi-application card (transit + loyalty + access) | DESFire EV2/EV3 or JCOP |
| Government ID / e-passport | JCOP with BAC/PACE (ISO/IEC 14443-B) |
| ← Chapter 5: NDEF Format | Table of Contents | Chapter 7: Hardware & Readers → |