Search code examples
androidnfcmifarelockbits

Mifare Ultralight C Lock


I'm attempting to lock a Mifare Ultralight C tag. I want to set NDEF pages 0x04 to 0x27 to read-only. I think this can be achieved via Ndef.makeReadonly().

Additionally, I would like to set pages 0x29 to 0x2F to be password protected (for read and write) so they can only be accessed after authentication was successful. I'm struggling to understand which bytes need to set in lock bytes (page 0x28, bytes 0, 1) and if sectors 0x2A and 0x2B need to be set as well.


Solution

  • I'm attempting to set NDEF pages 0x04 to 0x27 to readonly. I think this can be achieved via Ndef.makeReadonly().

    Not necessarily, Ndef.makeReadonly() might only set the read-only flag in the capability container (according to the NFC Forum Type 2 Tag Operation specification).

    If you want to make sure to set the actual lock bits, you would connect the tag as NfcA or MifareUltralight tag technology and issue a write command for the lock bits instead.

    NfcA nfcA = NfcA.get(tag);
    nfcA.connect();
    
    byte[] result1 = nfcA.transceive(new byte[] {
        (byte)0xA2,  /* CMD = WRITE */
        (byte)0x02,  /* PAGE = 2    */
        (byte)0x00, (byte)0x00, (byte)0xFF, (byte)0xFF  /* DATA = lock pages 3..15 */
    });
    
    byte[] result2 = nfcA.transceive(new byte[] {
        (byte)0xA2,  /* CMD = WRITE */
        (byte)0x28,  /* PAGE = 40   */
        (byte)0x0F, (byte)0x00, (byte)0x00, (byte)0x00  /* DATA = lock pages 16..27 */
    });
    

    Also see Mifare Ultralight: lock specific pages for the coding of the lockbits.

    I would like to set pages 0x29 to 0x2F to be password protected (for read and write) so they can only be accessed after authentication was successful.

    Using the write command that I showed above, you would first write your authentication key into pages 44..47. You would then write AUTH1 (page 43) as all-zeros. Finally, you would write AUTH0 (page 42) as 0x29 0x00 0x00 0x00 to require authentication for pages 41 and up. Actually I would suggest to lock pages 40 and up so that nobody could set the lock bits for those pages. Alternatively, you could set the block locking bits (i.e. write 0x1F 0x0F 0x00 0x00 to page 40) so that the lock bits for the unlocked pages cannot be changed.