MIFARE卡读取失败后的身份验证



arduino和mfrc522 rfid阅读器易于使用读写mifare卡。

我的目标是在一个扇区中使用卡的两个键,有些块可以用键 A 读取,有些块只能通过键 B 读取。

正确设置访问位允许此行为。为了在第二个扇区(块 4 5 6 7(上尝试一下,我设置访问位 g0 [0 0 0]、g1 [1 0 1]、g2 [0 0 0]、g3 [1 0 1],方法是用 {,0xF5,0xA5,0xA0,0x38,} 参见 https://www.nxp.com/docs/en/data-sheet/MF1S50YYX_V1.pdf §8.7 编写块 7。现在,块 5 不能用键 A 读取,而是用键 B (g1( 读取,而键 B 不再可读 (g3(。因此,当我使用 keyA 进行身份验证时,尝试读取块 5 会导致错误。此时,其他身份验证失败,并且无法读取其他块,尽管访问位允许这样做。

我尝试用键 B 读取第二个扇区,为块 5 和键 A 用于其他代码,它正在工作。但是,如果我尝试使用键 A 读取,然后在失败时使用键 B 读取,它不起作用。

代码摘录:

// The sector of interest is the second one : blocks 4 5 6 7
Serial.println("nAuthenticate block 0x05 with key B");
for (i = 4; i < 8; i++) {
// Block 5 is readable with key B
status = readblock(i==5?MF1_AUTHENT1B:MF1_AUTHENT1A, i, i==5?keyB:keyA, serial);
if ( status == MI_ERR) {
Serial.print(" - Unable to read block nb. 0x");
Serial.println(i, HEX);
}
}
Serial.println("nAuthenticate with key A then key B if failed");
for (i = 4; i < 8; i++) {
// Try to authenticate each block first with the A key.
status = readblock(MF1_AUTHENT1A, i, keyA, serial);
if ( status == MI_ERR) {
Serial.print(" - Try keyB - ");
status = readblock(MF1_AUTHENT1B, i, keyB, serial);
if ( status == MI_ERR) {
Serial.print(" - Unable to read block nb. 0x");
Serial.println(i, HEX);
}
}
}

读取块功能(身份验证和读取(

byte readblock(byte mode, byte block, byte *key, byte *serial)
{
int j;
byte data[MAX_LEN];
byte status = MI_ERR;
// Try to authenticate the block first
status = nfc.authenticate(mode, block, key, serial);
if ( status == MI_OK) {
Serial.print("Authenticated block nb. 0x");
Serial.print(block, HEX);
// Reading block i from the tag into data.
status = nfc.readFromTag(block, data);
if (status == MI_OK) {
// If there was no error when reading; print all the hex
// values in the data.
Serial.print(" : ");
for (j = 0; j < 15; j++) {
Serial.print(data[j], HEX);
Serial.print(", ");
}
Serial.println(data[15], HEX);
} else
Serial.print(" - Read failed");
} else {
Serial.print("Failed authentication block nb. 0x");
Serial.print(block, HEX);
}
return status;
}

结果是

Authenticate block 0x05 with key B
Authenticated block nb. 0x4 : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
Authenticated block nb. 0x5 : AB, CD, EF, 1, 23, 45, 67, 89, 98, 76, 54, 1A, 10, FE, DC, BA
Authenticated block nb. 0x6 : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
Authenticated block nb. 0x7 : 0, 0, 0, 0, 0, 0, F5, A5, A0, 38, 0, 0, 0, 0, 0, 0
Authenticate with key A then key B if failed
Authenticated block nb. 0x4 : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
Authenticated block nb. 0x5 - Read failed - Try keyB - Failed authentication block nb. 0x5 - Unable to read block nb. 0x5
Failed authentication block nb. 0x6 - Try keyB - Failed authentication block nb. 0x6 - Unable to read block nb. 0x6
Failed authentication block nb. 0x7 - Try keyB - Failed authentication block nb. 0x7 - Unable to read block nb. 0x7

所以我想知道是否有可能尝试使用坏键读取块,然后继续使用 othe rkey 读取块,依此类推。

解释可以在 https://www.nxp.com/docs/en/application-note/AN1304.pdf p.24中找到

每次身份验证操作、读取操作或写入操作失败时,MIFARE Classic 或 MIFARE Plus 将保持静默状态,不再响应任何命令。 在这种情况下,为了继续NDEF检测程序,需要重新激活并选择MIFARE Classic或MIFARE Plus。

因此,您必须在失败后重新激活并选择,例如将这些行添加到您的代码中:

Serial.println("nAuthenticate with key A then key B if failed");
for (i = 4; i < 8; i++) {
// Try to authenticate each block first with the A key.
status = readblock(MF1_AUTHENT1A, i, keyA, serial);
if ( status == MI_ERR) {
Serial.print(" - Try keyB - ");
/** RE ACTIVATE AND SELECT ------------------------------- **/
nfc.haltTag();
status = nfc.requestTag(MF1_REQIDL, data);
if (status == MI_OK) {
status = nfc.antiCollision(data);
memcpy(serial, data, 5);
nfc.selectTag(serial);
}
/** ------------------------------------------------------ **/
status = readblock(MF1_AUTHENT1B, i, keyB, serial);
if ( status == MI_ERR) {
Serial.print(" - Unable to read block nb. 0x");
Serial.println(i, HEX);
}
}
}

相关内容

最新更新