Задать вопрос
@Ilya52

Как скопировать ключ Mifare Classic с PN532 на Arduino?

Я написал код копировальщика ключей Mifare Classic 1K на Arduino для модуля PN532, но почему-то код он не может авторизоваться в секторах для записи данных. Не могу понять в чем проблема, буду очень благодарен если кто-то подскажет. Вот код:
#include <Wire.h>
#include <Adafruit_PN532.h>

// PN532 I2C setup (adjust pins if necessary, though often not needed for I2C)
#define PN532_IRQ   (4)  // Not used in I2C mode but required by library constructor
#define PN532_RESET (2)  // Not used in I2C mode but required by library constructor
Adafruit_PN532 nfc(PN532_IRQ, PN532_RESET);


// Buffer to store card data (16 sectors, 4 blocks each, but we copy 3 data blocks per sector)
byte cardData[64][16];  // 64 blocks total, 16 bytes each

// Default key (used in original code)
byte defaultKey[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

// Common keys for bruteforcing
byte commonKeys[][6] = {
  {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},  // Default key
  {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},  // All zeros
  {0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5},  // Common key A
  {0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5}   // Common key B
};
const int numCommonKeys = sizeof(commonKeys) / sizeof(commonKeys[0]);

void setup() {
  Serial.begin(9600);
  while (!Serial) delay(10);  // Wait for serial monitor

  nfc.begin();  // Initialize PN532
  uint32_t versiondata = nfc.getFirmwareVersion();
  if (!versiondata) {
    Serial.println("Couldn't find PN532 board");
    while (1);  // Halt
  }
  Serial.println("Found PN532");

  nfc.SAMConfig();  // Configure PN532 to read RFID tags
  Serial.println("Ready. Send 'r' to read source card, 'w' to write to target card.");
}
  
void loop() {
  if (Serial.available() > 0) {
    char command = Serial.read();
    if (command == 'r') {
      readSourceCard();
    } else if (command == 'w') {
      writeTargetCard();
    }
  }
}

// Read data blocks from source card
void readSourceCard() {
  uint8_t uid[] = {0, 0, 0, 0, 0, 0, 0};  // Buffer for UID
  uint8_t uidLength;                      // Length of UID

  Serial.println("Place source card on reader...");
  if (nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength)) {
    Serial.print("Source card UID: ");
    for (uint8_t i = 0; i < uidLength; i++) {
      Serial.print(uid[i], HEX);
      Serial.print(" ");
    }
    Serial.println();

    bool success = true;
    for (int sector = 0; sector < 16; sector++) {
      if (!readSector(sector, uid, uidLength)) {
        success = false;
        Serial.print("Failed to read sector ");
        Serial.println(sector);
      }
    }
    if (success) {
      Serial.println("Source card read successfully. Remove card and send 'w' to write.");
    }
  } else {
    Serial.println("No card detected or detection failed.");
  }
}

// Write data blocks to target card
void writeTargetCard() {
  uint8_t uid[] = {0, 0, 0, 0, 0, 0, 0};  // Buffer for UID
  uint8_t uidLength;                      // Length of UID

  Serial.println("Place target card on reader...");
  if (nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength)) {
    Serial.print("Target card UID: ");
    for (uint8_t i = 0; i < uidLength; i++) {
      Serial.print(uid[i], HEX);
      Serial.print(" ");
    }
    Serial.println();

    bool success = true;
    for (int sector = 0; sector < 16; sector++) {
      if (!writeSector(sector, uid, uidLength)) {
        success = false;
        Serial.print("Failed to write sector ");
        Serial.println(sector);
      }
    }
    if (success) {
      Serial.println("Target card written successfully.");
    }
  } else {
    Serial.println("No card detected or detection failed.");
  }
}

// Authenticate and read a sector's data blocks
bool readSector(int sector, uint8_t *uid, uint8_t uidLength) {
  uint8_t blockStart = sector * 4;
  bool authenticated = false;
  byte *keyUsed = defaultKey;

  // Try to authenticate with common keys as Key A
  for (int keyIndex = 0; keyIndex < numCommonKeys; keyIndex++) {
    if (nfc.mifareclassic_AuthenticateBlock(uid, uidLength, blockStart, 0, commonKeys[keyIndex])) {
      authenticated = true;
      keyUsed = commonKeys[keyIndex];
      break;
    }
  }

  if (!authenticated) {
    Serial.print("Authentication failed for sector ");
    Serial.println(sector);
    return false;
  }

  // Read data blocks (0, 1, 2 of each sector)
  for (int block = 0; block < 3; block++) {
    uint8_t blockNumber = blockStart + block;
    if (!nfc.mifareclassic_ReadDataBlock(blockNumber, cardData[blockNumber])) {
      Serial.print("Failed to read block ");
      Serial.println(blockNumber);
      return false;
    }
  }
  Serial.print("Sector ");
  Serial.print(sector);
  Serial.println(" read successfully.");
  return true;
}

// Authenticate and write a sector's data blocks
bool writeSector(int sector, uint8_t *uid, uint8_t uidLength) {
  uint8_t blockStart = sector * 4;

  // Authenticate with default key as Key A (assuming target card is new)
  if (!nfc.mifareclassic_AuthenticateBlock(uid, uidLength, blockStart, 0, defaultKey)) {
    Serial.print("Authentication failed for sector ");
    Serial.println(sector);
    return false;
  }

  // Write data blocks (0, 1, 2 of each sector)
  for (int block = 0; block < 3; block++) {
    uint8_t blockNumber = blockStart + block;
    if (!nfc.mifareclassic_WriteDataBlock(blockNumber, cardData[blockNumber])) {
      Serial.print("Failed to write block ");
      Serial.println(blockNumber);
      return false;
    }
  }
  Serial.print("Sector ");
  Serial.print(sector);
  Serial.println(" written successfully.");
  return true;
}
  • Вопрос задан
  • 19 просмотров
Подписаться 1 Средний Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы