【问题标题】:Authentication after a read failure of a MIFARE cardMIFARE 卡读取失败后的身份验证
【发布时间】:2018-08-27 18:01:13
【问题描述】:

一个 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,} 写入块 7 参见。 https://www.nxp.com/docs/en/data-sheet/MF1S50YYX_V1.pdf 的§8.7。现在块 5 不能用 keyA 而用 keyB (g1) 读取,并且 keyB 不再可读 (g3)。因此,当我使用 keyA 进行身份验证时,尝试读取块 5 会导致错误。此时其他验证失败,虽然访问位允许,但无法读取其他块。

我尝试用第 5 块的键 B 和其他代码的键 A 读取第二个扇区,它正在工作。但是,如果我尝试使用 key A 读取,然后使用 keyB 读取,以防万一失败。

代码摘录:

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

readblock函数(认证和读取)

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

所以我想知道是否可以尝试用坏密钥读取一个块,然后继续用另一个 rkey 读取块,等等。

【问题讨论】:

    标签: arduino rfid mifare


    【解决方案1】:

    解释可以在https://www.nxp.com/docs/en/application-note/AN1304.pdf第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);
                    }
                }
            }
    

    【讨论】:

    • 这就是为什么...否则,我想先阅读扇区预告片,然后为之后的块选择适当的密钥。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-24
    相关资源
    最近更新 更多