2082672_en-US

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

2082672_en-US

2082672_en-US

How can i enable CMAC, UID, COUNTER and RAND in NTAG424 DNA?

I'm trying to use the newest Android SDK library to set my dynamic URL based on AES key, but I'm unable to do it.

nxpnfcandroidlib-release-protected.aar

This is my code

override fun onNewIntent(intent: Intent) {
	Log.i("NFC", "Intent action: ${intent.action}")
	super.onNewIntent(intent)

	Log.i("MainActivity", "NFC tag discovered")

	val cardType = libInstance.getCardType(intent)
	Log.i("MainActivity", "Detected card type: $cardType")
	if (cardType == CardType.NTAG424DNA) {
	    val ntag424DNA: INTAG424DNA = DESFireFactory.getInstance().getNTAG424DNA(libInstance.customModules)
	    val reader: IReader = ntag424DNA.reader

	    try {

	        if (!reader.isConnected) {
	            reader.connect()
	        }

	        ntag424DNA.isoSelectApplicationByDFName(NTAG424DNA_APP_NAME)
	        Log.i("NFC", "ISO selected app by DF Name ")

	        authenticateTag(ntag424DNA, KEY_AES128_DEFAULT)
		    creatingNDEFmessage(ntag424DNA)
            authenticateTag(ntag424DNA, KEY_AES128_DEFAULT)
		    changeFileSettings(ntag424DNA, 0x01)

            authenticateTag(ntag424DNA, KEY_AES128_DEFAULT)
	        ntag424DNA.setPICCConfiguration(true)
	        Log.i("MainActivity", " PICC Configuration updated to enable SDM globally.")

	        authenticateTag(ntag424DNA, KEY_AES128_DEFAULT)
	        changeSDMFileSettings(ntag424DNA, 0x01)

	        if (reader.isConnected) {
	            reader.close()
	        }
	    } catch (e: Exception) {
	        e.printStackTrace()
	    }

	}
}

private fun creatingNDEFmessage(ntag424DNA: INTAG424DNA) {
    // 1. Creating URI NDEF message
    val msg = NdefMessageWrapper(
        NdefRecordWrapper(
            NdefRecordWrapper.TNF_ABSOLUTE_URI,
            "https://domain.com?uid=04BB38D2AA1191&ctr=0001&cmac=3ab665b76b795cb9bf76a17956cc9fb3&rand=422def08-8a1c-49c9-9138-434cde858faa".toByteArray(
                Charset.forName("US-ASCII")
            ), ByteArray(0), ByteArray(0)
        )
    )

    ntag424DNA.writeNDEF(msg);
    Log.i("MainActivity", "URI NDEF message written successful ")

    val ndefRead = ntag424DNA.readNDEF()
    Log.i("MainActivity", "Read URI NDEF message ${CustomModules.getUtility().dumpBytes(ndefRead.toByteArray())}")

}

private fun changeFileSettings(ntag424DNA: INTAG424DNA, fileNumber: Int) {
    // 3. Create NTAG 424 DNA file settings for E104
    val fileSettings = NTAG424DNAFileSettings(
        MFPCard.CommunicationMode.Encrypted,    // = 0x03 = Full ENC + CMAC (SUN)
        0x0E.toByte(),             // Read access = key slot 0x00 maybe 0x01
        0x0E.toByte(),             // Write access = always
        0x0E.toByte(),             // RW access = always
        0x0E.toByte()              // Change access = always
    )

    Log.i("MainActivity", "Prepare for saving changes in file $fileNumber")
    ntag424DNA.changeFileSettings(fileNumber, fileSettings)
    Log.i("NFC", " File settings updated $fileNumber")
}


private fun changeSDMFileSettings(ntag424DNA: INTAG424DNA, fileNumber: Int) {
    val fileSettings = ntag424DNA.getFileSettings(fileNumber);

    fileSettings.isSDMEnabled = true;
    fileSettings.isUIDMirroringEnabled = true;

    fileSettings.piccDataOffset = intTo2ByteArray(51)
    fileSettings.sdmMacOffset = intTo2ByteArray(51)
    fileSettings.sdmMacInputOffset = intTo2ByteArray(51)
    fileSettings.sdmReadCounterOffset = intTo2ByteArray(51)
    fileSettings.uidOffset = intTo2ByteArray(51)
    fileSettings.sdmAccessRights = byteArrayOf(0x00, 0x00)

    Log.i("MainActivity", "Prepare for saving SDM changes in file $fileNumber")
    ntag424DNA.changeFileSettings(fileNumber, fileSettings)
    Log.i("NFC", " File settings updated: SUN CMAC enabled on $fileNumber")
}

private fun intTo2ByteArray(value: Int): ByteArray {
    return byteArrayOf(
        ((value shr  and 0xFF).toByte(),
        (value and 0xFF).toByte()
    )
}

I know that the offset number doesn't match the position in the URL but whatever I'm changing, I'm still getting this error. It looks like, for some reason, these settings can not be saved by this method.

ntag424DNA.changeFileSettings(fileNumber, fileSettings)

This is the error message

com.nxp.nfclib.exceptions.UsageException: Invalid Parameters! {Invalid Value for PICC Offset}
Code examplesRe: How can i enable CMAC, UID, COUNTER and RAND in NTAG424 DNA?

The issue was due to the wrong offset value. It seems ntag reserved 21 default index. Now we are trying to change factory 128 aes key and changekey() function didnt work for us

@ukcas 

Re: How can i enable CMAC, UID, COUNTER and RAND in NTAG424 DNA?

hey there,

I am following this thread to set up JSON data, but it is not working for me. This is my first time working with hardware, which is making things much more challenging. I am using the NXP Android library and the sample Android application from here: https://www.nxp.com/design/design-center/software/rfid-developer-resources/taplinx-software-developm...

Below is my code inside Sample_Application_Android/src/main/java/com/nxp/sampletaplinx/WriteActivity.java

public static byte[] intTo2ByteArray(int value) {
    return new byte[] {
            (byte) (value & 0xFF),        // LSB
            (byte) ((value >> 8) & 0xFF), // middle byte
            (byte) ((value >> 16) & 0xFF) // MSB
    };
}

private void tag424DNACardLogic(INTAG424DNA ntag424DNA) {
    byte[] KEY_AES128_DEFAULT = new byte[] {
            (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
            (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
            (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
            (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
    };
    byte[] NTAG424DNA_APP_NAME =
            {(byte) 0xD2, (byte) 0x76, 0x00, 0x00, (byte) 0x85, 0x01, 0x01};
    byte[] data ={ 0x73, 0x75, 0x73, 0x68, 0x69, 0x6C };

    mStringBuilder.append("\n\n");
    int timeOut = 2000;
    try {
        ntag424DNA.isoSelectApplicationByDFName(NTAG424DNA_APP_NAME);
        KeyData aesKeyData = new KeyData();
        Key keyDefault = new SecretKeySpec(KEY_AES128_DEFAULT, "AES");
        aesKeyData.setKey(keyDefault);
       ntag424DNA.authenticateEV2First(0, aesKeyData, null);

        mStringBuilder.append(getString(R.string.Authentication_status_true));
        mStringBuilder.append("\n\n");

        ntag424DNA.setPICCConfiguration(true);

        String jsonTemplate = "{\"uuid\":\"00000000000000\",\"counter\":\"000000\",\"cmac\":\"0000000000000000\",\"domain1\":" + 1 + ",\"domain2\":" + 1 + "}";
        byte[] jsonBytes = jsonTemplate.getBytes("UTF-8");

        NTAG424DNAFileSettings fs = new NTAG424DNAFileSettings(
                CommunicationMode.Plain,  // or MAC/ENC depending on your security
                (byte) 0x0E, // Read access: Key 0
                (byte) 0x0E, // Write access: Key 0
                (byte) 0x0E, // Read/Write: Key 0
                (byte) 0x00  // Change access: Free
        );

        byte[] type = "U".getBytes("US-ASCII");
        fs.setSDMEnabled(true);
        fs.setUIDMirroringEnabled(true);
        fs.setSDMReadCounterEnabled(true);

        byte[] bytes = new byte[] { (byte)0xE0, (byte)0x00, (byte)0x00 };
        fs.setSdmAccessRights(bytes);

        byte[] uuidOffset = intTo2ByteArray(8);

        fs.setUidOffset(uuidOffset);

        byte[] readCounterOffset = intTo2ByteArray(35);
        fs.setSdmReadCounterOffset(readCounterOffset);

        byte[] macOffset = intTo2ByteArray(51);

        fs.setSdmMacInputOffset(uuidOffset);
        fs.setSdmMacOffset(macOffset);

        ntag424DNA.changeFileSettings(FILE_NUMBER, fs);

        // Create NDEF record
        NdefRecordWrapper record = new NdefRecordWrapper(
                NdefRecordWrapper.TNF_WELL_KNOWN,
                type,
                new byte[0],  // empty ID
                jsonBytes     // payload (your JSON)
        );

        // Wrap record into NDEF message
        NdefMessageWrapper msg = new NdefMessageWrapper(record);

        ntag424DNA.writeNDEF(msg);

        NxpLogUtils.save();
    } catch (Exception e) {
        writeFailedMessage();
        mStringBuilder.append(e.getMessage());

        Log.i("MainActivity", "URI NDEF message written successful $msg " + e.getMessage()  );
        showMessage(mStringBuilder.toString(), PRINT);
        NxpLogUtils.save();
    }

}

 would be great help if someone can assist me with this

Re: How can i enable CMAC, UID, COUNTER and RAND in NTAG424 DNA?

Thanks for the help! You are right that my offset has the wrong values. This is what I have changed and now I can save settings. 

override fun onNewIntent(intent: Intent) {
    Log.i("NFC", "Intent action: ${intent.action}")
    super.onNewIntent(intent)

    Log.i("MainActivity", "NFC tag discovered")

    val cardType = libInstance.getCardType(intent)
    Log.i("MainActivity", "Detected card type: $cardType")
    if (cardType == CardType.NTAG424DNA) {
        val ntag424DNA: INTAG424DNA = DESFireFactory.getInstance().getNTAG424DNA(libInstance.customModules)
        val reader: IReader = ntag424DNA.reader

        try {

            if (!reader.isConnected) {
                reader.connect()
            }

            ntag424DNA.isoSelectApplicationByDFName(NTAG424DNA_APP_NAME)
            Log.i("NFC", "ISO selected app by DF Name ")

            authenticateTag(0x00, ntag424DNA, KEY_AES128_DEFAULT)
            creatingNDEFmessage(ntag424DNA)
            authenticateTag(0x00, ntag424DNA, KEY_AES128_DEFAULT)
            changeFileSettings(ntag424DNA, 0x02)

            if (reader.isConnected) {
                reader.close()
            }
        } catch (e: Exception) {
            Log.e("MainActivity", e.localizedMessage ?: "No Error Message");
            e.printStackTrace()
        }

    }
}

private fun changeFileSettings(ntag424DNA: INTAG424DNA, fileNumber: Int) {
    // 3. Create NTAG 424 DNA file settings for E104
    val fileSettings = NTAG424DNAFileSettings(
        MFPCard.CommunicationMode.Plain,    // = 0x03 = Full ENC + CMAC (SUN)
        0x0E.toByte(),             // Read access = key slot 0x00 maybe 0x01
        0x0E.toByte(),             // Write access = always
        0x0E.toByte(),             // RW access = always
        0x00.toByte()              // Change access = always
    )

    fileSettings.isSDMEnabled = true
    fileSettings.isUIDMirroringEnabled = true
    fileSettings.isSDMReadCounterEnabled = true
    fileSettings.sdmAccessRights = byteArrayOf(0xfe.toByte(), 0xe1.toByte())

    fileSettings.uidOffset = byteArrayOf(0x1A, 0x00, 0x00)   
    fileSettings.sdmReadCounterOffset = byteArrayOf(0x2d, 0x00, 0x00) 
    fileSettings.sdmMacOffset = byteArrayOf(0x39, 0x00, 0x00) 
    fileSettings.sdmMacInputOffset = byteArrayOf(0x39, 0x00, 0x00)

    Log.i("MainActivity", "Prepare for saving changes in file $fileNumber")

    ntag424DNA.changeFileSettings(fileNumber, fileSettings)
    Log.i("MainActivity", " File settings updated $fileNumber")
}

private fun creatingNDEFmessage(ntag424DNA: INTAG424DNA) {
    // 1. Creating URI NDEF message
    val payload = byteArrayOf(0x04) + "noexample.xxxx?uid=00000000000000&ctr=000000&cmac=0000000000000000".toByteArray()

    val msg = NdefMessageWrapper(
        NdefRecordWrapper(
            NdefRecordWrapper.TNF_WELL_KNOWN,
            "U".toByteArray(StandardCharsets.US_ASCII),
            ByteArray(0),
            payload
        )
    )

    ntag424DNA.writeNDEF(msg);
    Log.i("MainActivity", "URI NDEF message written successful ")

    val ndefRead = ntag424DNA.readNDEF()
    Log.i("MainActivity", "Read URI NDEF message ${CustomModules.getUtility().dumpBytes(ndefRead.toByteArray())}")

}

Re: How can i enable CMAC, UID, COUNTER and RAND in NTAG424 DNA?

Dear Rocky2,

Please check document refered by jimmyvhan and datasheet. 


Your offsets are overlapping, which is not permitted as per datasheet.

Considering your desired URL. You have too less space for NFCCounter, which is 3 bytes. So below settings are suiting corrected URL.

https://domain.com?uid=04BB38D2AA1191&ctr=000001&cmac=3ab665b76b795cb9bf76a17956cc9fb3&rand=422def08...

 You shall use these parameters for SDM Configuration. You decide on Input data for CMAC calculation as well. We used UIDOffset as starting point for this example.

fileSettings.sdmMacOffset = intTo2ByteArray(53)
fileSettings.sdmMacInputOffset = intTo2ByteArray(22)
fileSettings.sdmReadCounterOffset = intTo2ByteArray(41)
fileSettings.uidOffset = intTo2ByteArray(22)

 Best regards,

TapLinx team

Re: How can i enable CMAC, UID, COUNTER and RAND in NTAG424 DNA?

This document could be useful for you.

NTAG 424 DNA and NTAG 424 DNA TagTamper features and hints

Tags (1)
No ratings
Version history
Last update:
‎11-21-2025 09:05 AM
Updated by: