Understanding Key Diversification in MIFARE DESFire - AccessGrid Guides
Understanding Key Diversification in MIFARE DESFire
September 16, 2025
Michael Pichardo
Overview
Key diversification is essential for secure DESFire implementation. This security technique generates unique keys for each card using a source key combined with the card's unique identifier (UID). Rather than deploying identical keys across all cards, diversification ensures that compromising one card doesn't expose the entire system.
NXP developed the technique and published the application note, AN10922, to teach the industry how key diversification could protect vulnerable MIFARE DESFire EV1 implementations from emerging attacks.
Why does this matter? In large-scale deployments like transit systems or corporate access control, thousands of cards are in circulation. Using static keys creates a single point of failure. If attackers extract one key, they can potentially access all cards in the system. Key diversification eliminates this vulnerability by making each card cryptographically unique while maintaining centralized key management.
A simplified key diversification algorithm example
The basic idea is to combine a source key with a unique identifier (UID) using a mathematical algorithm, such as a cryptographic hash or encryption function. The result is a diversified key that is unique to each card.
In this example, we are going to use a XOR-based diversification algorithm, a very simple (and insecure) algorithm. This isn’t to be used in production, but it clearly shows the mechanics of combining a source key with a card’s UID. Here are the same source key and card UID, but this time we padded the card id with more 0's to pad it to 16 bytes.
Source Key: 00112233445566778899AABBCCDDEEFF
Card UID: 04AABBCCDDEE00000000000000000000 (padded to 16 bytes)
Step 1: Line up the values
Write the source key and UID one on top of the other so each byte lines up
Source Key: 00 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF
Card UID: 04 AA BB CC DD EE 00 00 00 00 00 00 00 00 00 00
Step 2: Apply XOR, byte by byte XOR (Exclusive OR) is applied between corresponding bytes of the source Key and Card UID. Here's how the operation works:
For each byte position, we XOR the corresponding bytes from the source Key and card UID, and convert from binary to hex.
Diversified Key = HEX(Source Key XOR Card UID) byte by byte. This is the calculation for the first 4 bytes:
Position 1: 00 XOR 04 = 04
00000000 (Source Key byte 1: 00)
⊕ 00000100 (Card UID byte 1: 04)
--------
00000100 (Result: 04)
Position 2: 11 XOR AA = BB
00010001 (Source Key byte 2: 11)
⊕ 10101010 (Card UID byte 2: AA)
--------
10111011 (Result: BB)
Position 3: 22 XOR BB = 99
00100010 (Source Key byte 3: 22)
⊕ 10111011 (Card UID byte 3: BB)
--------
10011001 (Result: 99)
Position 4: 33 XOR CC = FF
00110011 (Source Key byte 4: 33)
⊕ 11001100 (Card UID byte 4: CC)
--------
11111111 (Result: FF)
Step 3: Put it back together
Put the result of the diversified key together. The process continues for the remaining bytes until all 16 are computed. Below are the first 4 bytes.
04 BB 99 FF ...
This example shows how the UID changes the source key into something unique per card. There are different algorithms ranging from simple to advanced. Some systems use DES, AES or 3DES encryption for diversification, while others use HMAC (hash-based message authentication code) or custom schemes. No matter the diversification algorithm used, the principle is the same: Source Key + Card UID → Diversified Key.
CMAC-Based Key Diversification (AN10922)
What is CMAC? CMAC (Cipher-based Message Authentication Code) is a cryptographic function that NXP recommends for key diversification. Unlike simple encryption, CMAC is a one-way function
Why CMAC instead of plain encryption?
- Security: CMAC prevents replay attacks and provides authentication
- One-way operation: Even if someone captures a diversified key, they cannot work backwards to find the source key
- Standardized: CMAC is defined in NIST SP 800-38B and widely used in secure systems
The AN10922 Algorithm
NXP's AN10922 application note defines the standard key diversification algorithm for MIFARE DESFire.
Here's how it works:
Inputs:
- Source Key (K): 16 bytes (AES-128)
- Diversification Input (M): 1-31 bytes (typically the card UID)
Output:
- Diversified Key: 16 bytes (AES-128)
Regardless of which algorithm is being used, the principle is the same. Here is a flow chart from NXP so you can visually see how both sides use the same algorithm to arrive to the same diversified key.
Algorithm Steps:
Step 1: Construct the Diversification Data
Start with a constant prefix 0x01, followed by your diversification input M (the card UID):
0x01 || M
Step 2: Apply Padding
If M is less than 31 bytes, padding is required:
- Append 0x80
- Append 0x00 bytes until the total length reaches 32 bytes
The padding scheme ensures a total of 32 bytes (two AES blocks).
Step 3: Determine the Padded Flag
Calculate a Boolean flag:
- Padded = true if M is less than 31 bytes
- Padded = false if M is exactly 31 bytes
Step 4: Compute CMAC
Diversified Key = AES128CMAC(K, D, Padded)
Where:
- K = Source key (16 bytes)
- D = Padded diversification data (32 bytes)
- Padded = Boolean flag
Processing Load: One AES-128 key load + 3 AES-128 computations
Ok, now let's walk through a real example and use CMAC to find the diversified key:
Given:
Source Key: 00112233445566778899AABBCCDDEEFF
Card UID: 04AABBCCDDEE (6 bytes)
Step 1: Construct with Constant
0x01 || 04AABBCCDDEE
= 0104AABBCCDDEE
Step 2: Apply Padding Since the UID is 6 bytes (less than 31), we need padding:
0x01 || 04AABBCCDDEE || 0x80 || 0x00... (until 32 bytes total)
Result (32 bytes):
01 04 AA BB CC DD EE 80 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Step 3: Set Padded Flag
Padded = true (because UID length 6 < 31)
Step 4: Compute CMAC
DiversifiedKey = AES128CMAC(
K = 00112233445566778899AABBCCDDEEFF,
D = 0104AABBCCDDEE80000000000000000000000000000000000000000000000000,
Padded = true
)
Note: The actual CMAC computation involves complex internal steps with subkey derivation (K1 and K2). The details are in NIST SP 800-38B, but most implementations use a library that handles this.
The AccessGrid key diversification algorithm
Great, now take a look at the AccessGrid key diversification strategy / algorithm guide. We do key diversification with 3 static keys (master (id: 00), read (id: 01), and privacy (id: 02)) and one standard file (id: 00) of max size 4096 bytes that uses encrypted communication with MACing for reads. The standard file can be read by using NXP’s AN10922 standard for key diversification.
Other factors when considering key diversification
Key diversification adds complexity to key management. Both the card and the backend system must be able to derive or store the diversified keys. This usually makes the system and hardware required to be more expensive.
If you lose the source key, you lose the ability to derive all diversified keys.
Diversification is not a substitute for other security measures. You should still have a layered security approach.
In real deployments, key diversification is strongly recommended for better security. On a high level, without key diversification or when systems use the same source key across all cards—they become vulnerable to systematic attacks.
Conclusion
Congrats, you made it to the end of the article. You learned why key diversification matters and how some of these key diversification algorithms work.