Authenticate and load keys fails Mifare Classic 4K

Viewed 167

I want to read the balance of my transport card (or at least able to read any sector) which has the following technologies: NfcA, Mifare Classic, Ndef Formattable. I found similar questions but none of them solved my issue.

I tried to authenticate using the default keys(keyA and keyB) but I could not.

Is there any way to authenticate my card? So far I tried these keys which I found from this link;

    defaultKeyList.add(new byte[] { (byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff});
    defaultKeyList.add(new byte[] { (byte)0xa0,(byte)0xb0,(byte)0xc0,(byte)0xd0,(byte)0xe0,(byte)0xf0});
    defaultKeyList.add(new byte[] { (byte)0xa1,(byte)0xb1,(byte)0xc1,(byte)0xd1,(byte)0xe1,(byte)0xf1});
    defaultKeyList.add(new byte[] { (byte)0xa0,(byte)0xa1,(byte)0xa2,(byte)0xa3,(byte)0xa4,(byte)0xa5});
    defaultKeyList.add(new byte[] { (byte)0xb0,(byte)0xb1,(byte)0xb2,(byte)0xb3,(byte)0xb4,(byte)0xb5});
    defaultKeyList.add(new byte[] { (byte)0x4d,(byte)0x3a,(byte)0x99,(byte)0xc3,(byte)0x51,(byte)0xdd});
    defaultKeyList.add(new byte[] { (byte)0x1a,(byte)0x98,(byte)0x2c,(byte)0x7e,(byte)0x45,(byte)0x9a});
    defaultKeyList.add(new byte[] { (byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00});
    defaultKeyList.add(new byte[] { (byte)0xaa,(byte)0xbb,(byte)0xcc,(byte)0xdd,(byte)0xee,(byte)0xff});
    defaultKeyList.add(new byte[] { (byte)0x71,(byte)0x4c,(byte)0x5c,(byte)0x88,(byte)0x6e,(byte)0x97});
    defaultKeyList.add(new byte[] { (byte)0x58,(byte)0x7e,(byte)0xe5,(byte)0xf9,(byte)0x35,(byte)0x0f});
    defaultKeyList.add(new byte[] { (byte)0xa0,(byte)0x47,(byte)0x8c,(byte)0xc3,(byte)0x90,(byte)0x91});
    defaultKeyList.add(new byte[] { (byte)0x53,(byte)0x3c,(byte)0xb6,(byte)0xc7,(byte)0x23,(byte)0xf6});
    defaultKeyList.add(new byte[] { (byte)0x8f,(byte)0xd0,(byte)0xa4,(byte)0xf2,(byte)0x56,(byte)0xe9});

And these are how I try to authenticate:

@Override
public void onTagDiscovered(Tag tag) {
    Log.d(TAG,"tag = "+tag.toString());
    Log.d(TAG,"tag describeContents = "+tag.describeContents());
    Log.d(TAG,"tag getId = "+ Arrays.toString(tag.getId()));
    Log.d(TAG,"tag getId = "+ Arrays.toString(tag.getTechList()));

    MifareClassic mifare = MifareClassic.get(tag);

        new Thread( new Runnable() { @Override public void run() {


            int ttype = mifare.getType();
            Log.d(TAG, "MifareClassic tag type: " + ttype);

            int tsize = mifare.getSize();
            Log.d(TAG, "tag size: " + tsize);

            int s_len = mifare.getSectorCount();
            Log.d(TAG, "tag sector count: " + s_len);

            int b_len = mifare.getBlockCount();
            Log.d(TAG, "tag block count: " + b_len);

            try {
                mifare.connect();
                if (mifare.isConnected()) {

                    for (byte[] key : defaultKeyList) {
                        for (int i = 0; i < s_len; i++) {

                            boolean isAuthenticated = false;

                            if (mifare.authenticateSectorWithKeyA(i, MifareClassic.KEY_MIFARE_APPLICATION_DIRECTORY) ||
                                    mifare.authenticateSectorWithKeyB(i, MifareClassic.KEY_MIFARE_APPLICATION_DIRECTORY)
                            ) {
                                isAuthenticated = true;
                            } else if (mifare.authenticateSectorWithKeyA(i, MifareClassic.KEY_DEFAULT) ||
                                    mifare.authenticateSectorWithKeyB(i, MifareClassic.KEY_DEFAULT)
                            ) {
                                isAuthenticated = true;
                            } else if (mifare.authenticateSectorWithKeyA(i, MifareClassic.KEY_NFC_FORUM) ||
                                    mifare.authenticateSectorWithKeyB(i, MifareClassic.KEY_NFC_FORUM)) {
                                isAuthenticated = true;
                            } else if (mifare.authenticateSectorWithKeyA(i, key) ||
                                    mifare.authenticateSectorWithKeyB(i, key)) {
                                isAuthenticated = true;
                            } else {
                                Log.d("TAG", "Authorization denied ");
                            }

                            if (isAuthenticated) {
                                Log.d("TAG", "isAuthenticated ");

                                int block_index = mifare.sectorToBlock(i);

                                byte[] block = mifare.readBlock(block_index);
                                String s_block = Utils.Companion.toHex(block);
                                Log.d(TAG, s_block);
                            }
                        }
                    }
                }

            } catch (IOException e) {
                e.printStackTrace();
            }
            catch (Exception e) {
                e.printStackTrace();
            }
                
        } } ).start();


}

And this is the result:

D/MainActivity: tag = TAG: Tech [android.nfc.tech.NfcA, android.nfc.tech.MifareClassic, android.nfc.tech.NdefFormatable]
D/MainActivity: tag describeContents = 0
D/MainActivity: tag getId = [-81, 53, -49, 18]
D/MainActivity: tag getId = [android.nfc.tech.NfcA, android.nfc.tech.MifareClassic, android.nfc.tech.NdefFormatable]
D/MainActivity: MifareClassic tag type: 0
D/MainActivity: tag size: 4096
D/MainActivity: tag sector count: 40
D/MainActivity: tag block count: 256
D/TAG: Authorization denied 
D/TAG: Authorization denied 
D/TAG: Authorization denied 
D/TAG: Authorization denied ... 

Authorization denied for all my keys. Also it is written that some sectors need both key A and key B but I do not know how to use both of them at the same time.

Is there any way to authenticate this? I also tried to load the keys but I could not manage to do that too. I used the following command:

byte[] LOADKEYS = {
            (byte) 0xFF, // CLA Class
            (byte) 0x82, // INS Instruction
            (byte) 0x00, // P1  Parameter 1
            (byte) 0x00, // P2  Parameter 2
            (byte) 0x06, // Length
            (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,(byte) 0xFF,(byte) 0xFF,(byte) 0xFF
    };

byte[] result = mifare.transceive(LOADKEYS)

And the response is always 10B2 It supposed to be 9000 or 6300. I could not find the meaning of the 10B2. I would really appreciate if someone can enlighten me. Thanks in advance.

0 Answers
Related