How to set and disable a password in the MIFARE Ultralight EV1 tag?

I would like to set and disable password protection on the MIFARE Ultralight EV1 (MFOUL21) tag using tag technology NfcA?

on Android.

I understand that I would use a method nfcA.transceive()

to do this, but I am not sure what the arguments for this method would be, so can someone provide code snippets for setting and unsetting a password?

Update:

As for the TapLinx library, basically I would like the code snippets to nfcA.transceive(...)

be the same:

  • ultralightEV1.programPwd(passwordBytes);

  • ultralightEV1.programPack(packBytes);

  • ultralightEV1.enablePasswordProtection(enabled, fromPageNum);

  • ultralightEV1.authenticatePwd(passwordBytes);

+3


source to share


2 answers


You can use NXP's TapLinx library (available at https://www.mifare.net/en/products/tools/taplinx/ ) to abstract communication with the MIFARE Ultralight EV1.

To use the "transceiver" according to the datasheet available at http://www.advanide.com/wp-content/uploads/products/rfid/UltraLight%20EV1_MF0ULX1.pdf , you must use the WRITE (A2) command from 25-28 hours.



UPDATE: The commands to be sent should be (for MFOUL21):

  • ultralightEV1.programPwd (passwordBytes); A227AABBCCDD (for password AABBCCDD)

  • ultralightEV1.programPack (packBytes); A228EEFF0000 (for PACK 0000)

  • ultralightEV1.enablePasswordProtection (enabled, fromPageNum); A225xx0000yy (where xx - modulation mode, 00..strut mode disabled, 01..built mod enabled, yy = page where password protection starts)

  • ultralightEV1.authenticatePwd (passwordBytes); 1BAABBCCDD

+1


source


Authenticate

ultralightEV1.authenticatePwd (passwordBytes);

To authenticate the password using the MIFARE Ultralight EV1 (or NTAG21x) tag, you need to send the PWD_AUTH (0x1B) command (and maybe check if the PACK response is what you expected):

byte[] pass = { (byte)0x12, (byte)0x34, (byte)0x56, (byte)0x78 };
byte[] pack = { (byte)0x9A, (byte)0xBC };

byte[] response = nfc.transceive(new byte[] {
    (byte) 0x1B, // PWD_AUTH
    pass[0], pass[1], pass[2], pass[3]
});
if ((response != null) && (response.length >= 2)) {
    // success
    byte[] packReceived = Arrays.copyOf(response, 2);
    if (Arrays.equal(packReceived, pack)) {
        // PACK verified, so tag is authentic (not really, but that whole
        // PWD_AUTH/PACK authentication mechanism was not really meant to
        // bring much security, I hope; same with the NTAG signature btw.)
    }
}

      

Set password and confirm password

ultralightEV1.programPwd (passwordBytes); ultralightEV1.programPack (packBytes);

For MF0UL11, the password is on page 0x12 and the PACK is on page 0x13 (configuration pages start at 0x10). For MF0UL21, the password is on page 0x27 and the PACK is on page 0x28 (configuration pages start at 0x25).

To dynamically find out if your tag is MF0UL11 or MF0UL21, you can send the GET_VERSION (0x60) command:



int cfgOffset = -1;

byte[] response = nfc.transceive(new byte[] {
    (byte) 0x60 // GET_VERSION
});
if ((response != null) && (response.length >= 8)) {
    // success
    if ((response[0] == (byte)0x00) && (response[1] == (byte)0x04)) {
        // tag is from NXP
        if (response[2] == (byte)0x03) {
            // MIFARE Ultralight
            if ((response[4] == (byte)0x01) && (response[5] == (byte)0x00) {
                // MIFARE Ultralight EV1 (V0)
                switch (response[6]) {
                    case (byte)0x0B:
                        // MF0UL11
                        cfgOffset = 0x010;
                        break;
                    case (byte)0x0E:
                        // MF0UL11
                        cfgOffset = 0x025;
                        break;

                    default:
                        // unknown
                        break;
                }
            }
        }
    }
}

      

Once you know about the beginning of the configuration pages, you can use the WRITE (0xA2) command to update the values ​​of these pages (assuming you are authenticated with the current password, if the configuration pages are not secure):

byte[] response = nfc.transceive(new byte[] {
    (byte) 0xA2, // WRITE
    (byte)((cfgOffset + 2) & 0x0FF),    // page address
    pass[0], pass[1], pass[2], pass[3]  // new page data
});
response = nfc.transceive(new byte[] {
    (byte) 0xA2, // WRITE
    (byte)((cfgOffset + 3) & 0x0FF),          // page address
    pack[0], pack[1], (byte)0x00, (byte)0x00  // new page data (always need to write full page)
});

      

Enable password protection

ultralightEV1.enablePasswordProtection (enabled, fromPageNum);

To enable password protection, you need to configure the first page that requires a password (AUTH0, byte 3 on page 0x10 for MF0UL11 / page 0x25 MF0UL21), and you need to configure the protection mode (PROT, bit 7 of byte 0 on page 0x11 for MF0UL11 / page 0x26 MF0UL21).

Typically you would first read (READ (0x30)) the old value of these pages, update the affected bits and bytes, and write the new value to the tag:

int fromPageNum = 4;
boolean enableProtection = true;
boolean enableReadProtection = true;
byte[] response = nfc.transceive(new byte[] {
    (byte) 0x30, // READ
    (byte)(cfgOffset & 0x0FF)  // page address
});
if ((response != null) && (response.length >= 16)) {
    // success
    // NOTE that READ will return *4 pages* starting at page address
    byte auth0 = (byte)0xFF;
    if (enableProtection || enableReadProtection) {
        auth0 = (byte)(fromPageNum & 0x0FF);
    }
    byte[] writeResponse = nfc.transceive(new byte[] {
        (byte) 0xA2, // WRITE
        (byte)((cfgOffset + 0) & 0x0FF),              // page address
        response[0], response[1], response[2], auth0  // new page data
    });
    byte access = (byte)(response[4] & 0x07F);
    if (enableProtection && enableReadProtection) {
        access |= (byte)0x80;
    }
    byte[] writeResponse = nfc.transceive(new byte[] {
        (byte) 0xA2, // WRITE
        (byte)((cfgOffset + 1) & 0x0FF),                // page address
        access, response[5], response[6], response[7],  // new page data
    });
}

      

+1


source







All Articles