Clonar una tarjeta RFID con Arduino

힘센캥거루
2025년 11월 26일
5
38

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.

관련 글

Programar un robot araña con micro:bit
Programar un robot araña con micro:bit
Esta vez, en un encuentro relacionado con tecnología robótica, se abrió gratuitamente una clase.Era una capacitación en el uso de la micro:bit para co...
Recopilación de datos de temperatura y humedad con Arduino ESP32
Recopilación de datos de temperatura y humedad con Arduino ESP32
Hoy crearemos una garita meteorológica WiFi que mide la temperatura y la humedad utilizando el Arduino ESP32. Este contenido está basado en el guión de clases 16+1 que se llevará a cabo en la escuela. 1. Materiales necesarios. Los materiales son simples. ESP32, DHT-22, 3 cables. Primero, expliquemos brevemente el ESP32...
Experiencia usando Arduino D1 R2
Experiencia usando Arduino D1 R2
Podría haberlo hecho simplemente con un Arduino Uno, pero decidí probar el Wemos D1 R2 con WiFi integrado y terminé teniendo bastantes problemas. Este artículo es para aquellos que usan un Arduino con mapeo de pines diferente, como el D1 R2. 1. Configuración del IDE El Arduino tiene tantos tipos ...
Cómo resolver 'Timed out waiting for packet header' en Arduino en MacBook
Cómo resolver 'Timed out waiting for packet header' en Arduino en MacBook
Método para resolver el problema de 'Timed out' al conectar Arduino Wemos D1 R2 en MacBook
Conectar Arduino con una hoja de cálculo - Configuración del código
Conectar Arduino con una hoja de cálculo - Configuración del código
En el artículo anterior, hablamos sobre la configuración de la hoja para conectar Arduino con una hoja de cálculo. En este artículo, aprenderemos cómo enviar datos desde el tablero Arduino D1 utilizando comunicación HTTPS. 1. Instalar la biblioteca del tablero Arduino D1 Para utilizar el tablero Arduino D1, primero debemos instalar la biblioteca del tablero...
Conexión de Arduino con Hoja de Cálculo - Configuración de Google Sheets
Conexión de Arduino con Hoja de Cálculo - Configuración de Google Sheets
Recientemente decidimos con los estudiantes usar Arduino para observar la temperatura y humedad alrededor de la escuela y analizar los valores. Necesitábamos una tarjeta SD para guardar los datos medidos por Arduino, y era un inconveniente retirar la tarjeta SD para verificar los datos. De repente pensé ¿qué tal si ...

댓글을 불러오는 중...