On an NTAG215 card I need to store a decimal value for example 5432.50 and a JWT of approximately 350 characters. Initially I saved both data with NdefMessage but I implemented the authentication mechanism on the card by enabling a password for write operations, using MifareUltralight
The jwt value does not change once initially established, but the numerical value does, in order to decrease monetary balance.
According to the MIFARE Ultralight protocol documentation always writes 1 page (4 bytes). at a time, for example for 5432.50, you have to write on page 4 “5432” and on page 5 “.500” and for the jwt, from page 6 to 94, but there are some pages in that range that they are not for data.
What is the correct way to do this logic?
fun writeAndProtectTag(intent: Intent) {
Thread(object : Runnable {
var pwd = "-_bA".toByteArray() //Password has to be 4 characters
var pack = "cC".toByteArray() //Password Acknowledge has to be 2 characters
override fun run() {
val tag = intent.getParcelableExtra<Tag>(NfcAdapter.EXTRA_TAG)
var mifare: MifareUltralight? = null
try {
mifare = MifareUltralight.get(tag)
mifare.connect()
while (!mifare.isConnected) {
}
var response: ByteArray?
// Authenticate with the tag first
try {
response = mifare.transceive(
byteArrayOf(
0x1B.toByte(), // PWD_AUTH
pwd[0], pwd[1], pwd[2], pwd[3]
)
)
// Check if PACK is matching expected PACK
if (response != null && response.size >= 2) {
val packResponse = Arrays.copyOf(response, 2)
if (!(pack[0] == packResponse[0] && pack[1] == packResponse[1])) {
Log.d("NFC", "Tag could not be authenticated:\n$packResponse≠$pack")
} else {
try {
mifare.writePage(4, "5432".encodeToByteArray())
mifare.writePage(5, ".500".encodeToByteArray())
//TODO write jwt
} catch (e: UnsupportedEncodingException) {
e.printStackTrace()
} catch (e: IOException) {
e.printStackTrace()
}
}
}
} catch (e: IOException) {
e.printStackTrace()
}
} catch (e: IOException) {
e.printStackTrace()
} catch (e: java.lang.Exception) {
e.printStackTrace()
}
try {
mifare!!.close()
} catch (e: IOException) {
e.printStackTrace()
}
}
}).start()
}
I don't quite understand your question but I think you are miss understanding the page numbers.
An NTAG215 data pages are "04h to 81h for NTAG215" or 4
to 129
in decimal but as the pages start at 0
and it includes the start page, then that give you 126 pages (126 x 4 = 504).
You jwt needs 350 bytes (88 pages) thus uses up to 94 in decimal or 5Eh
which is much lower than the max page you can use of 81h
thus you won't come anywhere near the configuration pages starting at 82h
.
I think that you have confused 81h
in hex as 81 in decimal and thus you think your jwt data would override the config pages, which it will not.
Otherwise at a glance the code logic looks OK, just split you jwt bytes in to groups of 4 and write them to incrementing pages numbers from 06h