为 NTAG213 设置密码

Setting password for NTAG213

我正在尝试在 NFC 标签(类型:NTAG213)中设置和检查密码,但我在尝试设置时总是收到 IOException(收发失败)。

我不明白我必须在哪个页面设置密码和ACK包。 这是我用 C# 和 Xamarin 编写的代码。请随时使用原生 Android Java 代码回复。

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 
});

对于 NTAG213,密码 (PWD) 和密码确认 (PACK) 的正确页面是:

  • 密码: 43 (0x2B)
  • 包装:44 (0x2C)

因此,您正在尝试写入错误的页面。更具体地说,您正试图将非零值写入 RFUI 字节(第 44 页,字节 2-3 和第 42 页,字节 1-3),这可能会导致写入操作失败。

所以你通常会想做这样的事情:

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]
});

请注意,让 PACK 成为 PWD 的子集没有多大意义,因为攻击者随后可以从 PWD 值中获取 PACK 值。 PACK 值通常用作只有您和标签“知道”的共享秘密,并且标签发送以响应成功的身份验证尝试,以证明它是真正的标签。 (尽管这种方法存在很多安全问题。)

进一步注意,如果标签已经受到保护(密码设置和身份验证配置设置为保护 PWD/PACK),设置 PWD/PACK 值将失败(可能带有 IOException)。在这些情况下,您需要先使用当前密码进行身份验证。