Search code examples
androidtagsnfcmifarelockbits

How to write protect an NTAG203 NFC chip programmatically on android?


I've been looking into NTAG203 NFC chips for a membership card solution and intend to set up and write a unique ID onto each card.

Oddly I can't find much online about how to write protect NTAG203 chips although I can find write-protected ones being sold. I've also seen apps which offer the write protection service.

How do you code an android app to enable write protection on an NTAG203?

Thanks!

(Edited question for clarity)


Solution

  • Yes, that's possible. NTAG203 (datasheet) is an ISO/IEC 14443 Type A ("NFC-A") tag and follows the NFC Forum Type 2 Tag Operation specification. In order to activate the physical write protection feature of such a tag, you need to set the lock bits.

    On Android, you can access such a tag by obtaining an instance of the NfcA technology connector class for your tag handle:

    Tag tag = ...  // I assume you already received the tag handle by means of an NFC discovery intent
    NfcA nfcA = NfcA.get(tag);
    if (nfcA != null) {
        // this is an NFC-A tag
        ...
    

    The lock bits of NTAG203 are located in page 2 (0x02) bytes 2-3 and in page 40 (0x28) bytes 0-1. Each of the bits of those 4 bytes controls the lock state of certain pages of the NTAG203 memory area. In order to activate locking, you have to set the lock bit to '1' by issuing a write command for the pages containing the lock bits. So for the simplest scenario of locking the whole tag, you could do something like this:

        // connect to the tag
        nfcA.connect();
    
        byte[] result;
        // write all-ones to the lock bits on page 0x02
        result = nfcA.transceive(new byte[]{
                (byte)0xA2,  // Command: WRITE
                (byte)0x02,  // Address: page 0x02 (2)
                (byte)0x00, (byte)0x00, (byte)0xFF, (byte)0xFF  // Data: set bytes 2-3 to all '1'
        });
        // write all-ones to the lock bits on page 0x28
        result = nfcA.transceive(new byte[]{
                (byte)0xA2,  // Command: WRITE
                (byte)0x02,  // Address: page 0x28 (40)
                (byte)0xFF, (byte)0x11, (byte)0x00, (byte)0x00  // Data: set byte 0 and lock bits in byte 1 to all '1'
        });
    
        nfcA.close();