Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting password for NTAG213

I am trying to set and check a password in a NFC Tag (type: NTAG213) but I always receive an IOException (Transceive failed) when I am trying to set it.

I don't understand which page I have to set for password and ACK pack. This is my code written in C# with Xamarin. Please feel free to reply in native Android Java code.

var tag = intent.GetParcelableExtra (NfcAdapter.ExtraTag) as Tag;

String password = "pass";
byte[] array = System.Text.Encoding.ASCII.GetBytes (password);
MifareUltralight mifare = MifareUltralight.Get (tag);
mifare.Connect ();

byte[] result1 = mifare.Transceive(new byte[] {
        (byte)0xA2,  /* CMD = WRITE */
        (byte)0x2C,  /* PAGE = 44 */
        array[0], array[1], array[2], array[3] 
});

byte[] result2 = mifare.Transceive(new byte[] {
        (byte)0xA2,  /* CMD = WRITE */
        (byte)0x2A,  /* PAGE = 42 */
        (byte)array[0], (byte)array[1], (byte)0, (byte)0 
});
like image 713
lukaspp Avatar asked Feb 18 '26 19:02

lukaspp


1 Answers

With NTAG213, the correct pages for the password (PWD) and the password acknowledge (PACK) are:

  • PWD: 43 (0x2B)
  • PACK: 44 (0x2C)

Hence, you are trying to write to the wrong pages. More specifically, you are trying to write non-zero values to RFUI bytes (page 44, bytes 2-3 and page 42, bytes 1-3) which may cause the write operations to fail.

So you would typically want to do something like this:

byte[] pwd = new byte[] { (byte)0x70, (byte)0x61, (byte)0x73, (byte)0x73 };
byte[] pack = new byte[] { (byte)0x98, (byte)0x76 };

// write PACK:
byte[] result = mifare.Transceive(new byte[] {
        (byte)0xA2,  /* CMD = WRITE */
        (byte)0x2C,  /* PAGE = 44 */
        pack[0], pack[1], 0, 0
});

// write PWD:
result = mifare.Transceive(new byte[] {
        (byte)0xA2,  /* CMD = WRITE */
        (byte)0x2B,  /* PAGE = 43 */
        pwd[0], pwd[1], pwd[2], pwd[3]
});

Note that it does not make much sense to let PACK be a subset of PWD since an attacker would then be able to obtain the PACK value from the PWD value. The PACK value is typically used as a shared secret that only you and the tag "know" and that the tag sends in response to a successful authentication attempt in order to prove that it is a genuine tag. (Though there are quite a lot of security issues with this approach.)

Further note that setting the PWD/PACK values will fail (possibly with an IOException) if the tag is already protected (password set and authentication configuration set to protect PWD/PACK). In those cases, you would need to authenticate with the current password first.

like image 160
Michael Roland Avatar answered Feb 21 '26 09:02

Michael Roland



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!