4
votes

I would like to read a specific block on Mifare classic using Java's javax.smartcardio. Here's my code:

public byte[] getCardUID() throws CardException {
    CardTerminals terminals = TerminalFactory.getDefault().terminals();
    terminal = terminals.list().get(0);
    Card card = terminal.connect("*");
    CardChannel channel = card.getBasicChannel();
    CommandAPDU command = new CommandAPDU( new byte[] { (byte) 0xFF, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x04, (byte) 0xD4, (byte) 0x4A, (byte) 0x01, (byte) 0x00 });
    ResponseAPDU response = channel.transmit(command);
    card.disconnect(true);
    if (response.getSW1() == 0x90) {
        byte[] data = response.getData();
        data = Arrays.copyOfRange(data, 0x08, data.length);
        return data;
    }
    return new byte[] {};
}

This method (sample found on internet) successfully reads the UID of the card, but when I try to construct my own command, I always become error SW1=63.

On this site (http://www.acs.com.hk/drivers/eng/API_ACR122U_v2.00.pdf) i have found some informations about APDU, but nothing is working and i cannot find out why. I have tried following command without success (always error 63): FF B0 00 04 10 (B0 - read binary block, 04 - number of sector, 10 - read 16 bytes). I have also tried reading only one byte, reading value block (INS B1) but also no success.

FF 00 00 00 ... (from my example) should be a direct transmit, but i don't know following instructions for reading a block.

Can anyone help me? Thanks a lot. (Sorry for my english)

1
You are in fact using an ACR122U, right?martijno
Yes, I'm not 100% sure because i havent installed this driver, but i think I'm using acr122u. Btw. my reader is touchatag.user1607656
Ok, as far as I know you should be able to use these proprietary APDUs to talk to your mifare, so you should in principle be able to do this using javax.smartcardio. Maybe the traffic is going to the internal SAM smart card instead of to the mifare card? If you open your reader, does it contain a contact smart card?martijno
I thought, that it should be possible because of succesfull UID reading. I cannot see any screwdrivers on my reader and honestly I would rather leave my reader unopened. I tried to find some technical details, but no success. Theoretically, if the redaer has a internal SAM smart card, what does it mean and what is the difference in the communication?user1607656
So, i have found out, that in my reader is a contact smart card that looks like a SIM card in mobile phone.user1607656

1 Answers

7
votes

In Mifare Classic 1K tags There are 16 Sectors and each Sectors contains 4 Blocks and each block contains 16 bytes. Before Reading or writing from a page You must have to Authenticate The Sector using Key A or Key B. When Authentication is complete then you can read or write. Here is the Authentication Command Authenticate sector 0 using that key as key A (60):

FF 86 0000 05 01 0000 60 00

Or authenticate sector 0 using that key as key B(61):

FF 86 0000 05 01 0000 61 00

or using this command you can also authenticate sector 0

byte[] authenticationByte = new byte[10];
authenticationByte = new byte[] { (byte) 0xFF, (byte) 0x86, (byte) 0x00,
 (byte) 0x00, (byte) 0x05, (byte) 0x00,(byte) 0x00, (byte) 0x04, 
                                    (byte) 0x60,(byte) 0x00 };

When Authentication is succes then you will get 90 00. That is Success message. Else response is 63 00 , that means authentication failed. When Authentication complete then you can read block (0,1,2,3) cause sector 0 contains 4 block and those are block (0,1,2,3).

Using this command You can read data from Sector 0 block 1

byte[] readFromPage = new byte[10];
readFromPage = new byte[] { (byte) 0xFF, (byte) 0x00, (byte) 0x00,
 (byte) 0x00, (byte) 0x05, (byte) 0xD4, (byte) 0x40,
 (byte) 0x00, (byte) 0x30, (byte) 0x01 };

Here last (byte) 0x01 is block where you want to read. in this answer you can find the complete code. Just replace the byte value using this. Thanks.