Search code examples
javaandroidmifare

Is it possible to lock command, protect cloning or not erasable by other app for MIFARE card 1k


I want to do this to protect the card from erasable or cloning the card. I read many documents Some tell the user the fourth block to set permission to reading and write..

According to @Michael Roland

The authentication keys and the access conditions for each sector of a MIFARE card are located in the last block of that sector (the sector trailer). You can update this block with new access conditions and authentication keys using a regular write command.

The sector trailer looks like this:

+-----------------------------+--------------+----+-----------------------------+
|  0 |  1 |  2 |  3 |  4 |  5 |  6 |  7 |  8 |  9 | 10 | 11 | 12 | 13 | 14 | 15 |
+-----------------------------+--------------+----+-----------------------------+
|            Key A            | Access Bits  | GP |            Key B            |
|          (6 bytes)          |  (3 bytes)   | B  |          (6 bytes)          |
+-----------------------------+--------------+----+-----------------------------+

So the access bits are located in byte 6-8 and look like this:

        +-------+-------+-------+-------+-------+-------+-------+-------+
        | Bit 0 | Bit 1 | Bit 2 | Bit 3 | Bit 4 | Bit 5 | Bit 6 | Bit 7 |
        +-------+-------+-------+-------+-------+-------+-------+-------+
Byte 6: | nC2_3 | nC2_2 | nC2_1 | nC2_0 | nC1_3 | nC1_2 | nC1_1 | nC1_0 |
        +-------+-------+-------+-------+-------+-------+-------+-------+
Byte 7: |  C1_3 |  C1_2 |  C1_1 |  C1_0 | nC3_3 | nC3_2 | nC3_1 | nC3_0 |
        +-------+-------+-------+-------+-------+-------+-------+-------+
Byte 8: |  C3_3 |  C3_2 |  C3_1 |  C3_0 |  C2_3 |  C2_2 |  C2_1 |  C2_0 |
        +-------+-------+-------+-------+-------+-------+-------+-------+

Where nCx_y = not Cx_y and "C1_x, C2_x, C3_x" is the access condition for block x:

C1_3, C2_3, C3_3: sector trailer (block 3 in this sector)
C1_2, C2_2, C3_2: block 2 in this sector
C1_1, C2_1, C3_1: block 1 in this sector
C1_0, C2_0, C3_0: block 0 in this sector

How I perform this in my ongoing project

enter image description here

enter image description here


Solution

  • Finally, I solved this solution

    For this, we need to change the access bits in each sector on Fourth block

    For Example on Sector 5

    Just like for sector 5 we need to change access bits on 23 blocks of it's

    We need to first authenticate the sector 5...

    The Default key is

    byte keya[] = { (byte) 0xFF,(byte) 0xFF,(byte) 0xFF,(byte) 0xFF,(byte) 0xFF,(byte) 0xFF};
    

    Which is 000000000000FF078069FFFFFFFFFFFF

    the First Bit 6 is for Key A which is 000000000000 and last 6 his for key B which is FFFFFFFFFFFF hex string

    FF078069 hex string is access bits

    so for change this we need to implementation like this for the first time we need to authenticate with default key

      MifareClassic mfc = MifareClassic.get(tag);
    
            try {
                mfc.connect();
                auth = mfc.authenticateSectorWithKeyA(5, 
     MifareClassic.KEY_DEFAULT);
            if(auth)
            {
             String nkeya = "key123";// 6 length only
                    nkeya = toHex(nkeya).toUpperCase();
                    nkeya = nkeya.substring(28,40);
    
                    String nkeyb = "key123"; // 6 length only
                    nkeyb = toHex(nkeyb).toUpperCase();
                    nkeyb = nkeyb.substring(28,40);
    
                    String nkey = nkeya+"FF078069"+nkeyb;
                    int len = nkey.length();
    
                    byte[] nkeyab = new BigInteger(nkey, 16).toByteArray();
                    // 5 is sector and 5*4+3 is fourth block of sector 5
                    mfc.writeBlock((5*4)+3,nkeyab);
    
    }
    catch(Execption e)
     {
     }
    

    After successfully write protection Default Authentication is failed So we need to authenticate with Access key which we create

    try {
     MifareClassic mfc = MifareClassic.get(tag);
     String key = getKeya();
    
     key = toHex(key).toUpperCase();
      int len = key.length();
       key = key.substring(28,40);
       keya = new BigInteger(key, 16).toByteArray();
    
      //for key A or for Keb b
    
    
                mfc.connect();
                auth = mfc.authenticateSectorWithKeyA(5, keya);
            if(auth)
            {
    
    
      byte[] readblock4=    mfc.readBlock(20);
    
      }
      }
     catch(Exeption e)
     {
    
     }