I'm trying to read some information out of an ISO/IEC 14443 Type A card.
After analysing the card with the android app NFC TagInfo, I found out, that the application (AID: 15845F) has the particular file (File ID: 01) that I need.
I already managed to connect to the card and to select the application.
String action = getIntent().getAction();
if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(action))
{
Tag tagFromIntent = getIntent().getParcelableExtra(NfcAdapter.EXTRA_TAG);
Log.i(TAG, Arrays.toString(tagFromIntent.getTechList()));
IsoDep isoDep = IsoDep.get(tagFromIntent);
try
{
isoDep.connect();
byte[] SELECT = {
(byte) 0x00, // CLA = 00 (first interindustry command set)
(byte) 0xA4, // INS = A4 (SELECT)
(byte) 0x04, // P1 = 04 (select file by DF name)
(byte) 0x0C, // P2 = 0C (first or only file; no FCI)
(byte) 0x06, // Lc = 6 (data/AID has 6 bytes)
(byte) 0x31, (byte) 0x35,(byte) 0x38,(byte) 0x34,(byte) 0x35,(byte) 0x46 // AID = 15845F
};
byte[] result = isoDep.transceive(SELECT);
Log.i(TAG, "SELECT: " + bin2hex(result));
if (!(result[0] == (byte) 0x90 && result[1] == (byte) 0x00))
throw new IOException("could not select application");
byte[] GET_STRING = {
(byte) 0x00, // CLA Class
(byte) 0xB0, // INS Instruction
(byte) 0x00, // P1 Parameter 1
(byte) 0x00, // P2 Parameter 2
(byte) 0x04 // LE maximal number of bytes expected in result
};
result = isoDep.transceive(GET_STRING);
Log.i(TAG, "GET_STRING: " + bin2hex(result));
}
}
But my second query fails with the error code: 6A86 (Incorrect parameters P1-P2). I already googled a lot and found different documentations (for example: http://bit.ly/180b6tB), but I just could not understand, how I can implement the right values for P1 and P2.
EDIT
Tag type of the card using NFC TagInfo: ISO/IEC 14443-4 Smart Card, Mifare DESFire EV1 (MF3ICD81)
The SELECT command as used in the source code actually did not fail, but instead it returned a 9000 response. So this is why I assumed that everything is working fine.
You mentioned that NFC TagInfo does not provide the correct values for DF-names etc. Is the value 0x313538343546 correct and how did you find it out?
Can you provide me a short description, how I could get the data I want? Are there any other android apps that I can use to read the right DF-names, AIDs etc.? I basically need to get ONE file out of ONE application. I could also provide some screenshots of the information gathered with NFC TagInfo, if needed.
EDIT 2
I have rewritten the commands, but (as you proposed) kept them in the APDU wrapper. Therefore I ended up having two different commands, one for the selection of the application and the other one for the selection of the file.
private final byte[] NATIVE_SELECT_APP_COMMAND = new byte[]
{
(byte) 0x90, (byte) 0x5A, (byte) 0x00, (byte) 0x00, 3, // SELECT
(byte) 0x5F, (byte) 0x84, (byte) 0x15, (byte) 0x00 // APPLICATION ID
};
private final byte[] NATIVE_SELECT_FILE_COMMAND = new byte[]
{
(byte) 0x90, (byte) 0xBD, (byte) 0x00, (byte) 0x00, 7, // READ
(byte) 0x01, // FILE ID
(byte) 0x00, (byte) 0x00, (byte) 0x00, // OFFSET
(byte) 0x00, (byte) 0x00, (byte) 0x00, // LENGTH
(byte) 0x00
};
The search for a tutorial for native Mifire-Desfire commands was not successful, so I stick to the following tutorial: http://noobstah.blogspot.de/2013/04/mifare-desfire-ev1-and-android.html
This tutorial provides a card authentification, which I disabled, and also uses the transceive method, which for my understanding is not a proper way for executing native commands? Which method, purhaps even code snippit, is used for executing native commands? Which Android-Class should I use?
I have rewritten the class provided in the tutorial and uploaded it to pastebin. After executing the class I've got following results.
Select APPLICATION: 9100
Read DATA: 91AE
At this point I am quite stuck and do not know what steps I should do next. Was is actually the error or rather what changes in the queries should I perform, to get the data I want?