Reputation: 13
I have an NFC tag with support for NfcA
and MifareClassic
technologies. After a firmware update, my phone does not support the MifareClassic
technology anymore. On older firmware, reading the MifareClassic
tag worked fine.
Is it possible to use the NfcA
class to read the Mifare Classic tag? How can this be done?
The key for authenticating the technology of Mifare Classic A0A1A2A3A4A5 (For example)
public static String[] readTag(Tag tag) {
byte[] readedData;
byte[] PASSWORD = new byte[]{(byte) 0xA0, (byte) 0xA1, (byte) 0xA2, (byte) 0xA3, (byte) 0xA4, (byte) 0xA5};
NfcA nfca = NfcA.get(tag);
try {
nfca.connect();
readedData = nfca.transceive(new byte[]{
(byte) 0x30,
(byte) (0 & 0x0ff),PASSWORD // (for example)
});
} catch (Exception e) {
}
}
Upvotes: 1
Views: 3249
Reputation: 40831
First of all, in order to communicate (i.e. authenticate, perform read/write operations) with MIFARE Classic tags, you will need a device with NFC hardware that supports MIFARE Classic. Due to NXP's licensing policies, this is typically only possible on devices with NFC chipsets from NXP. Other NFC chipsets will usually only allow you to perform anti-collision and enumeration (i.e. detect the tag and read its (N)UID).
Since you indicated that the capability to access MIFARE Classic (through the MifareClassic
tag technology object) was lost as a result of a firmware update, I would assume that your NFC chipset is capable of accessing MIFARE Classic.
NXP's NFC controllers transparently abstract access to MIFARE Classic tags with MIFARE reader commands (plain-text commands for authentication, binary read/write, and value block operations). The chipset automatically takes care of translating these abstract commands to actual MIFARE Classic commands, mutual authentication, and session encryption. The MifareClassic
tag technology object implements the following commands:
authenticateSectorWithKeyA(sectorIndex, key)
: +----------+-------------+--------------------+-------------------+ | 0x60 | BLOCK_INDEX | UID (last 4 bytes) | KEY_A | | (1 byte) | (1 byte) | (4 bytes) | (6 bytes) | +----------+-------------+--------------------+-------------------+
authenticateSectorWithKeyB(sectorIndex, key)
: +----------+-------------+--------------------+-------------------+ | 0x61 | BLOCK_INDEX | UID (last 4 bytes) | KEY_B | | (1 byte) | (1 byte) | (4 bytes) | (6 bytes) | +----------+-------------+--------------------+-------------------+
readBlock(blockIndex)
: +----------+-------------+ | 0x30 | BLOCK_INDEX | | (1 byte) | (1 byte) | +----------+-------------+
writeBlock(sectorIndex, data)
: +----------+-------------+--------------------+ | 0xA0 | BLOCK_INDEX | DATA | | (1 byte) | (1 byte) | (16 bytes) | +----------+-------------+--------------------+
increment(blockIndex, value)
: +----------+-------------+-------------------+ | 0xC1 | BLOCK_INDEX | VALUE | | (1 byte) | (1 byte) | (4 bytes) | +----------+-------------+-------------------+
decrement(blockIndex, value)
: +----------+-------------+-------------------+ | 0xC0 | BLOCK_INDEX | VALUE | | (1 byte) | (1 byte) | (4 bytes) | +----------+-------------+-------------------+
transfer(blockIndex)
: +----------+-------------+ | 0xB0 | BLOCK_INDEX | | (1 byte) | (1 byte) | +----------+-------------+
restore(blockIndex)
: +----------+-------------+ | 0xC2 | BLOCK_INDEX | | (1 byte) | (1 byte) | +----------+-------------+
For current NFC controllers (those that use NCI; not applicable to e.g. PN544) these commands are wrapped into special NCI commands by the Android NFC system service (see phNxpExtns.c and phNxpExtns_MifareStd.c).
Depending on why your device fails to enumerate the MifareClassic
tag technology, you might be lucky and the NFC stack of your device already handles that wrapping. In that case, you should be able to send the above commands using the NfcA
tag object.
However, you device might fail to enumerate the MifareClassic
tag technology because it simply detects the tag as regular Type 2 tag (or other NFC-A tag). In that case, NativeNfcTag.cpp will not perform the additional wrapping. You might still be able to acutally create the wrapped commands by following the same strategy that's performed in phNxpExtns.c and phNxpExtns_MifareStd.c. However, I'm not sure what other side-effects the incorrect detection might have (e.g. different interface initialization).
Upvotes: 2