在 NTAG215 卡上,我需要存储一个十进制值(例如 5432.50)和大约 350 个字符的 JWT。 最初我使用 NdefMessage 保存了这两个数据,但我通过使用 MifareUltralight
为写入操作启用密码来实现卡上的身份验证机制jwt 值一旦建立就不会改变,但数值会改变,以减少货币余额。
根据 MIFARE Ultralight 协议文档始终写入 1 页(4 个字节)。例如,对于 5432.50,您必须在第 4 页上写“5432”,在第 5 页上写“.500”,而对于 jwt,则必须在第 6 页到第 94 页上写,但有些页面不在该范围内用于数据。
执行此逻辑的正确方法是什么?
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()
}
我不太明白你的问题,但我认为你错过了理解页码。
NTAG215 数据页为“NTAG215 的 04h 至 81h”或十进制的
4
129
,但页面从 0
开始,为您提供 126 页 (126 x 4 = 504)。
您的 jwt 需要 350 字节(88 页),因此十进制最多为 94 或
5Eh
,这远低于您可以使用的最大页面 81h
,因此您不会接近从 82h
开始的配置页面
.
我认为你的
81h
是十进制的81,因此认为你的jwt数据会覆盖配置页面,但事实并非如此。
否则乍一看代码逻辑看起来不错,只需将 jwt 字节分成 4 组,然后将它们写入从
06h
开始递增的页码