Importing MIFARE Classic keys - metrodroid/metrodroid GitHub Wiki
Importing MIFARE Classic keys
There are three types of key files that can be imported into Metrodroid:
-
JSON, which is supported by Metrodroid v2.9.36 and later.
These files have an association with a particular card, and are imported with the "JSON key file" option.
-
Static JSON, which is supported by Metrodroid v2.9.36 and later.
These files are used for any card, and are also imported with the "JSON key file" option.
-
Raw MIFARE Classic keys (aka: "farebotkeys"), which is supported by all versions of Metrodroid.
This format is limited and error-prone, and no longer recommended for use. These files have no association with a particular card. On adding the key, you are prompted to scan a card to link the keys with.
Metrodroid ships with the following keys, and will always try to authenticate with them as a fall-back:
000000000000: All zeros, used as a default key on some cards.FFFFFFFFFFFF: The MFC factory default key.A0A1A2A3A4A5: Key for cards formatted according to the MIFARE Application Directory (MAD) specificationD3F7D3F7D3F7: Key for cards formatted according to the NDEF on MIFARE Classic specification
Metrodroid does not ship with other static keys. Many transit agencies use a key diversification function, which gives unique keys to every single card.
JSON
This file type is supported by Metrodroid v2.9.36 and later. This is the internal format that Metrodroid uses to store keys.
A typical key file has the following format:
{
"KeyType": "MifareClassic",
"TagId": "12345678", /* 4 byte, base16 encoded UID (optional) */
"keys": [
{ /* key for sector 0 */
"type": "KeyA", /* or "KeyB" */
"key": "010203040506" /* 6 byte, Base16 encoded string of the key for sector 0 */
},
{ /* key for sector 1 */
"type": "KeyA", /* or "KeyB" */
"key": "102030405060" /* 6 byte, Base16 encoded string of the key for sector 1 */
},
/* ... other sectors... */
]
}
Note: Comments have been added to this example as an aid, but JSON does not support comments and these will need to be removed.
There is no requirement for every sector to be supplied, or for them to be in the correct order. However, if you have many unique keys for each sector, it is recommended to put the keys in the correct order for speedy authentication.
JSON key files may have an association with a particular card (TagId). One can override this association during the key import process. However, once imported, the link cannot be modified.
Static JSON
This file type is supported by Metrodroid v2.9.36 and later.
This is a variant of the JSON format, which allows the same key to be used for multiple cards. This is useful for storing keys where the issuer doesn't implement key diversification.
{
"KeyType": "MifareClassicStatic",
"Description": "a human-readable label",
"keys": [
{ /* sector 0 key */
"type": "KeyA", /* or "KeyB" */
"key": "010203040506", /* 6 byte, Base16 encoded string of the key for sector 0 */
"sector": 0 /* sector this key applies to */
},
{ /* other sector 0 key */
"type": "KeyA", /* or "KeyB" */
"key": "102030405060", /* 6 byte, Base16 encoded string of the key for sector 1 */
"sector": 0 /* sector this key applies to */
},
/* ... other sectors... */
]
}
Note: Comments have been added to this example as an aid, but JSON does not support comments and these will need to be removed.
Key bundles
This option is supported by Metrodroid v2.9.38 and later.
bundle is a string parameter, that allows grouping a collection of static keys within a single key file. If a static key with a bundle was used successfully, it'll try keys from the same bundle first -- making reading cards with static keys faster.
Consider this example static key file:
{
"KeyType": "MifareClassicStatic",
"Description": "my key file",
"keys": [
{
"type": "KeyA",
"key": "102030405060",
"sector": 0,
"bundle": "alpha"
},
{
"type": "KeyA",
"key": "112233445566",
"sector": 1,
"bundle": "alpha"
}, /* other sectors here... */
{
"type": "KeyA",
"key": "010203040506",
"sector": 0,
"bundle": "beta"
},
{
"type": "KeyA",
"key": "aabbccddeeff",
"sector": 1,
"bundle": "beta"
}, /* other sectors here... */
/* other keys ... */
]
}
If 010203040506 worked to authenticate Sector 0 Key A, then the bundle would be recorded (beta). Then, when Sector 1 key is requested, Metrodroid would try aabbccddeeff first, because it has the same bundle.
Transformed keys
This option is supported by Metrodroid v2.9.39 and later.
This instructs Metrodroid to apply a key diversification function (KDF) to the given keys:
none(default, if not specified): does nothingtouchngo: Touch 'n Go KDF (Malaysia), see tng2json.py
Keys may be have an additional transform parameter:
{
"KeyType": "MifareClassicStatic",
"Description": "a human-readable label",
"keys": [
{
"type": "KeyA", /* or "KeyB" */
"key": "010203040506", /* 6 byte, Base16 encoded string of the key for sector 0 */
"sector": 0, /* sector this key applies to */
"transform": "none" /* default behaviour: perform no transformation */
},
{ /* other sector 0 key */
"type": "KeyA", /* or "KeyB" */
"key": "102030405060", /* 6 byte, Base16 encoded string of the key for sector 1 */
"sector": 1, /* sector this key applies to */
"transform": "touchngo" /* perform transform for Touch 'n Go KDF */
},
/* ... other sectors... */
]
}
Note: Comments have been added to this example as an aid, but JSON does not support comments and these will need to be removed.
Note: This only really makes sense for use with Static JSON keys.
Raw (farebotkeys)
This file type is supported by all versions of Metrodroid, and is inherited from Farebot. This format is very limited and error-prone, and no longer recommended for use.
Files are simply a concatenation of each sector's 6-byte key as binary data, in the order of the sectors on the card. The file sizes are:
| Card type | Number of sectors | File size |
|---|---|---|
| MIFARE Classic 1K | 16 | 96 bytes |
| MIFARE Classic 4K | 40 | 240 bytes |
In Metrodroid v2.9.22 and later, the keys no longer need to be in the correct order, and repeated keys may be omitted. However, if there are 16 unique keys in use on the card, it is recommended to put them in the correct order, otherwise authentication will be significantly slower.
File sizes could be as small as 6 bytes (for 1 key used on every sector), and are always a multiple of 6 bytes. The previous file sizes become a maximum file size.
In Metrodroid v2.9.33 and later, it will always try to authenticate using both key slots, and selecting "Key A" or "Key B" only changes which key slot it tries first.
Tools
extra/mfcdump_convert.py: Extracts keys from a MFC / MFD dump from tools like mfoc, mfcuk or Proxmark3'sdumpdata.bin, and outputs it in various formats.extra/textkeys_to_farebotkeys.py: Converts new-line separated Base16-encoded keys to the old "raw" binary format.