Understanding Key Diversification in MIFARE DESFire
Access Control Protocols
Michael Pichardo
Overview
Key diversification is essential for secure DESFire implementation. This security technique generates unique keys for each card using a master 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:
When XORing two bytes, each bit position is compared individually:
If the bits at the same position are identical (0⊕0 or 1⊕1) → result bit is 0
If the bits at the same position are different (0⊕1 or 1⊕0) → result bit is 1
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:
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 - you can derive a diversified key from a source key and UID, but you cannot reverse the process to recover the source key.
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
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.
Key diversification flow chart from NXP
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:
DiversifiedKey = AES128CMAC(
K = 00112233445566778899AABBCCDDEEFF,
D = 0104AABBCCDDEE80000000000000000000000000000000000000000000000000,
Padded = true
)
The CMAC algorithm will process these two AES blocks using the source key, applying the CMAC construction (which involves subkey generation and XOR operations).
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.
CMAC Construction Diagram
The CMAC process can be visualized as:
Block 1: [01 04 AA BB CC DD EE 80 00 00 00 00 00 00 00 00]
↓
AES Encrypt with K
↓ (XOR with next block)
Block 2: [00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00]
↓
AES Encrypt with K (with subkey XOR)
↓
[Diversified Key - 16 bytes]
Two cases exist:
Without padding (M = 31 bytes): Last block XORed with subkey K1
With padding (M < 31 bytes): Last block XORed with subkey K2
Note: Yes, I understand I am not showing you the algorithm of how NXP encrypts the key. This is just a simplified overview from the docs. The goal is to explain the core principles of how such an algorithm works, so you can infer how more advanced or proprietary key diversification methods might operate.
Why is this secure?
One-way: Cannot derive source key from diversified key
Unique per card: Different UIDs produce completely different keys
Collision resistant: Extremely unlikely for two UIDs to produce the same key
Always validate that the UID length is between 1-31 bytes
Store source keys securely (HSM, secure enclave, etc.)
The diversified key should never be stored - always derive it on-demand
Both the card initialization system and the backend verification system must use the exact same algorithm. The reader and the device both run the algorithm and get to the same result independently about what the diversified key actually is.
The output of this encryption is the diversified key which is unique to the card, yet still tied back to the source key.
Another important concept to note is the following: when there's key diversification on a mobile wallet transmitting a signal to a reader, MIFARE DESFIRE is using the same algorithm and material/params as the person putting the key into a smartcard. Thus, the reader doesn't know anything about the key when the signal is transmitted to it, but both the device and the reader use the algorithm to calculate the diversified key and they should both reach the same result.
You might wonder: Why Not Simple Encryption? Why not just encrypt the UID with the source key?
What's ECB? Electronic Codebook (ECB) is the most basic encryption mode, it simply encrypts data block-by-block with no additional security measures.
Problems with this approach:
ECB creates patterns: Identical input blocks produce identical output blocks, making it vulnerable to analysis
No authentication: Anyone can tamper with the input or output without detection
Not a proper Key Derivation Function (KDF): Doesn't follow cryptographic standards for deriving keys from other keys
Limited security validation: ECB is generally considered insecure for most applications
Why CMAC is better: CMAC (Cipher-based Message Authentication Code) is specifically designed for key derivation. It includes authentication to prevent tampering, avoids ECB's pattern vulnerabilities, and follows industry-standard practices (NIST SP 800-108) for secure key generation.
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. We also give an example / practical exercise.
Other factors when considering key diversification
Now, that we understand the high level of how it works and why it's important, it's also good to note some of the 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. Don't believe me, just read the "Quick primer on Key Diversification" section in this guide.
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. If your organization is interested in digitizing the experience of issuing and managing mobile credentials, remember that AccessGrid.com can handle the entire process for you with its API, streamlining operations, saving you effort and reducing errors. If you have any questions or need assistance, just use the chat or email [email protected] for help.