Аутентификация после сбоя чтения карты MIFARE - PullRequest
0 голосов
/ 25 августа 2018

Arduino и RFID-считыватель mfrc522 просты в использовании для чтения и записи mifare-карт.

Моя цель - использовать оба ключа карты в секторе, некоторые блоки читаются с помощью клавиши A,а некоторые доступны для чтения только по ключу B.

Правильная установка битов доступа позволяет такое поведение.Чтобы попробовать его на втором секторе (блоки 4 5 6 7), я установил биты доступа g0 [0 0 0], g1 [1 0 1], g2 [0 0 0], g3 [1 0 1] с помощьюзапись блока 7 с {, 0xF5,0xA5,0xA0,0x38,} ср.§8.7 из https://www.nxp.com/docs/en/data-sheet/MF1S50YYX_V1.pdf. Теперь блок 5 читается не ключом A, а ключом B (g1), а ключ B больше не читается (g3).Поэтому, когда я аутентифицируюсь с ключом A, попытка чтения блока 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);
            }
        }
}

функция 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

Поэтому я хотел бы знать, можно ли попытаться прочитать блок с использованием плохого ключа, а затем продолжить чтение блока с помощью клавиши Rothe Rkeyи т. д.

1 Ответ

0 голосов
/ 27 августа 2018

Объяснение можно найти в 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);
                }
            }
        }
...