Clonar una tarjeta RFID con Arduino

힘센캥거루
2025년 11월 26일
9
arduino

Hoy voy a escribir sobre cómo clonar una tarjeta RFID con Arduino.

Como no me olvido de lo que escribo una vez, lo dejo aquí a modo de repaso.

Clonar una tarjeta RFID con Arduino-1

1. Estructura interna de datos de una tarjeta RFID

La tarjeta RFID típica es una tarjeta MIFARE Classic 1K.

La estructura de memoria de esta tarjeta es la siguiente.

- Total 1024 bytes (1KB)
- 16 Sectores (0~15)
- Cada Sector tiene 4 Bloques (Block 0~3)
- Cada Bloque tiene 16 bytes

Cada sector tiene la siguiente estructura.

Sector n
 ├── Block 0 (Data or UID block)
 ├── Block 1 (Data)
 ├── Block 2 (Data)
 └── Block 3 (Sector Trailer: Key A, Access Bits, Key B)

Entre estos sectores, el que tiene el significado más importante es el primer dato del sector 0.

Ahí es donde se almacena el UID.

Clonar una tarjeta RFID con Arduino-2

2. UID

Es la abreviatura de Unique IDentifier, y se refiere al número de identificación único asignado a cada tarjeta RFID (por ejemplo: tarjeta de transporte, tarjeta de acceso, tarjeta de estudiante, etc.).

En el caso de una persona, cumple un papel similar al número de documento de identidad.

El UID se almacena en los primeros 4 bytes dentro del Block 0 del Sector 0.

[ UID0 | UID1 | UID2 | UID3 | BCC | Manufacturer Data… ]

Cuando una máquina RFID lee una tarjeta, lo primero que lee es esta parte.

Con esto se lleva a cabo la identificación de la tarjeta.

Clonar una tarjeta RFID con Arduino-3

3. Tarjeta CUID

Lo importante es que el UID de una MIFARE Classic 1K original queda fijado en fábrica.

En los chips originales de NXP el UID se almacena en la ROM y no puede modificarse por ningún método.

Por lo tanto, con un lector de tarjetas normal o con el MFRC522 no es posible modificar el UID.

Clonar una tarjeta RFID con Arduino-4

Sin embargo, en el mercado existen tarjetas en las que es posible cambiar el UID, y a este tipo de tarjetas se les llama CUID (también conocidas como tarjetas mágicas).

La C del principio significa Changeable.

Su aspecto externo es igual al de una MIFARE Classic 1K, pero el chip interno es diferente de la siguiente manera.

① Gen1A (compatible con UID/Backdoor)

  • Soporta los comandos de backdoor 0x40 / 0x43

  • Proporciona un comando específico para cambiar el UID

  • Se puede cambiar con MFRC522 + la función MIFARE_SetUid() de la librería de Arduino

② CUID / Gen2 (Block 0 Writable)

  • No tiene comandos de backdoor

  • En su lugar, está diseñada para poder sobrescribir el Block 0 (el sector donde está el UID) mediante una escritura normal (WRITE)

  • Es posible cambiar el UID si el MFRC522 acepta el comando MIFARE_Write(0…)

  • Pero no todos los CUID funcionan así. Si el MFRC522 no lo soporta, se necesita PN532/ACR122U

4. Clonar una tarjeta RFID con Arduino

Ahora que ya conocemos el principio, el método para clonar una tarjeta RFID con Arduino es sencillo.

Solo hay que clonar el UID.

Primero conecta el Arduino como se muestra a continuación.

Clonar una tarjeta RFID con Arduino-5

Signal

MFRC522 Pin

Arduino Uno / 101

Arduino Mega

Arduino Nano v3

Arduino Leonardo / Micro

Arduino Pro Micro

RST / Reset

RST

9

5

D9

RESET / ICSP-5

RST

SPI SS

SDA (SS)

10

53

D10

10

10

SPI MOSI

MOSI

11 / ICSP-4

51

D11

ICSP-4

16

SPI MISO

MISO

12 / ICSP-1

50

D12

ICSP-1

14

SPI SCK

SCK

13 / ICSP-3

52

D13

ICSP-3

15

Luego, en el IDE de Arduino, busca e instala la librería MFRC522.

Clonar una tarjeta RFID con Arduino-6

Ahora ve a Archivo -> Ejemplos -> MFRC522 y selecciona ReadNUID.

Clonar una tarjeta RFID con Arduino-7

Después de subir ese código, primero lee el valor del UID.

El UID suele estar formado por 4 valores hexadecimales.

F5 5F 36 80

 Si has obtenido un UID como el de arriba, el UID que se va a subir es el siguiente.

El 0x delante del número significa que ese número está en hexadecimal.

0xF5 0x5F 0x36 0x80

5. Problemas y solución

Quería resolverlo fácilmente con el ejemplo ChangeUID, pero seguía fallando.

El backdoor 0x40 daba continuamente timeout.

Resultó que mi tarjeta era Gen2, así que solo tenía que acceder al sector 0 y reemplazar el UID.

El código es el siguiente.

#include <SPI.h>
#include <MFRC522.h>

#define RST_PIN  9
#define SS_PIN   10

MFRC522 mfrc522(SS_PIN, RST_PIN);
MFRC522::MIFARE_Key key;

// Nuevo UID que se quiere poner (4 bytes)
byte newUid[4] = { 0xF5, 0x5F, 0x36, 0x80 };  // Ejemplo

void setup() {
  Serial.begin(9600);
  while (!Serial) {}

  SPI.begin();
  mfrc522.PCD_Init();
  Serial.println(F("Ejemplo de escritura directa del UID en el Block 0 de una tarjeta CUID"));

  // Configurar clave por defecto FF..FF
  for (byte i = 0; i < 6; i++) {
    key.keyByte[i] = 0xFF;
  }
}

void loop() {
  // Esperar nueva tarjeta
  if (!mfrc522.PICC_IsNewCardPresent() || !mfrc522.PICC_ReadCardSerial()) {
    return;
  }

  Serial.print(F("UID actual de la tarjeta: "));
  for (byte i = 0; i < mfrc522.uid.size; i++) {
    Serial.print(mfrc522.uid.uidByte[i], HEX);
    Serial.print(" ");
  }
  Serial.println();

  // === 1. Autenticar Sector 0 (Block 0) ===
  byte block = 0;  // Block 0
  MFRC522::StatusCode status;

  status = mfrc522.PCD_Authenticate(
      MFRC522::PICC_CMD_MF_AUTH_KEY_A,
      block,
      &key,
      &(mfrc522.uid)
  );

  if (status != MFRC522::STATUS_OK) {
    Serial.print(F("Fallo de autenticación: "));
    Serial.println(mfrc522.GetStatusCodeName(status));
    goto HALT;
  }

  // === 2. Leer el contenido actual del Block 0 para conservar la parte del fabricante ===
  byte block0[18];  // 16 bytes + información de tamaño
  byte size = sizeof(block0);
  status = mfrc522.MIFARE_Read(0, block0, &size);

  if (status != MFRC522::STATUS_OK) {
    Serial.print(F("Fallo al leer Block 0: "));
    Serial.println(mfrc522.GetStatusCodeName(status));
    goto HALT;
  }

  // block0[0..3] = UID original
  // block0[4]    = BCC (XOR de los 4 bytes del UID)
  // block0[5..15]= datos del fabricante, etc.

  // === 3. Calcular nuevo UID + BCC y sobrescribir ===
  byte bcc = newUid[0] ^ newUid[1] ^ newUid[2] ^ newUid[3];

  block0[0] = newUid[0];
  block0[1] = newUid[1];
  block0[2] = newUid[2];
  block0[3] = newUid[3];
  block0[4] = bcc;
  // Si dejamos block0[5..15] tal cual, se mantiene la información del fabricante

  status = mfrc522.MIFARE_Write(0, block0, 16);
  if (status != MFRC522::STATUS_OK) {
    Serial.print(F("Fallo al escribir en Block 0: "));
    Serial.println(mfrc522.GetStatusCodeName(status));
    goto HALT;
  }

  Serial.println(F("Escritura del nuevo UID completada. Retira la tarjeta y vuelve a acercarla."));

HALT:
  mfrc522.PICC_HaltA();
  mfrc522.PCD_StopCrypto1();

  delay(1000);
} 

6. Conclusión

En esta ocasión he llegado a entender bien cómo usar el módulo RFID.

Si buscas por ahí, verás proyectos que abren puertas usando una tarjeta llave, y parece que algo así también se podría implementar fácilmente.

Quiero probar a aplicarlo de diversas maneras.

Por cierto, si con este método la tarjeta sigue sin ser reconocida, es muy probable que se trate de un problema de frecuencia (13,56 MHz, 125 kHz, etc.).

Si tienes alguna pregunta, déjala en los comentarios.

댓글을 불러오는 중...