ESP32 MFRC522 e intento de cambio de clave si tiene la de fábrica

Hola, buenas tardes,

Estoy intentando programar el ESP para que cuando acerco una tarjeta cambie la clave de un sector si ese sector tiene la clave de fabrica:

hay una nueva tarjeta
....tiene la clave de fabrica
........cambiarla por la nueva clave
....no tiene la clave de fabrica
........verificar que sea la nueva clave

tengo dos versiones del código, el primero es este:

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

//------------------------------------------------------------------------------
//#### MODULO RFID ####

#define MFRC522_RST_PIN       0
#define MFRC522_SS_PIN        5

/********************************/

#define CLV_NVA_0     0xAA
#define CLV_NVA_1     0xBB
#define CLV_NVA_2     0xCC
#define CLV_NVA_3     0xDD
#define CLV_NVA_4     0xEE
#define CLV_NVA_5     0xFF

/********************************/


MFRC522 mfrc522(MFRC522_SS_PIN, MFRC522_RST_PIN);

byte finalDelSector[18] = {CLV_NVA_0, CLV_NVA_1, CLV_NVA_2, CLV_NVA_3,
                           CLV_NVA_4, CLV_NVA_5, /* 6 primeros nueva clave */
                           0xFF, 0x7, 0x80, 0x69, /* 4 siguientes FF, 7, 80, 69 */
                           0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
                          }; /* 6 ultimos FF */
byte bloqueObjetivo = 31;

/******************************************************************************/

void setup()
{
  Serial.begin(115200);

  SPI.begin();
  mfrc522.PCD_Init();

  Serial.println(F("Escribir datos personales en un PICC MIFARE "));
}


/******************************************************************************/

void loop()
{
  if ( ! mfrc522.PICC_IsNewCardPresent() ) return;

  if ( ! mfrc522.PICC_ReadCardSerial() ) return;

  //----------------------------------------------------------------------------

  Serial.print(F("Tag ID:"));
  for (byte i = 0; i < mfrc522.uid.size; i++)
  {
    Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
    Serial.print(mfrc522.uid.uidByte[i], HEX);
  }
  Serial.print(F(" Tipo Tag: "));
  MFRC522::PICC_Type piccType = mfrc522.PICC_GetType(mfrc522.uid.sak);
  Serial.println(mfrc522.PICC_GetTypeName(piccType));
  Serial.println("");
  Serial.println("");

  //----------------------------------------------------------------------------

  MFRC522::StatusCode estClvFabrica = tarjetaTieneClaveDeFabrica(bloqueObjetivo);
  if ( estClvFabrica == MFRC522::STATUS_OK )
  {
    Serial.print("Cambiando clave de fabrica");
    MFRC522::StatusCode estadoCambioClave = cambiarClaveDeFabrica(bloqueObjetivo);
    if ( estadoCambioClave == MFRC522::STATUS_OK )
    {
      Serial.print("  **** Clave cambiada : ");
    }
    Serial.print("  ");
    Serial.println(mfrc522.GetStatusCodeName(estadoCambioClave));
  }
  else
  {
    Serial.println("ERROR en la clave de fabrica : ");
    Serial.println(mfrc522.GetStatusCodeName(estClvFabrica));
    
    Serial.println("");
    
    MFRC522::StatusCode estVerifClaveNueva;
    Serial.print("**** Verificando clave nueva : ");
    estVerifClaveNueva = verificarClaveNueva(bloqueObjetivo);
    Serial.println(mfrc522.GetStatusCodeName(estVerifClaveNueva));
  }

  //----------------------------------------------------------------------------

  Serial.println("");
  Serial.println("");
  
  mfrc522.PICC_HaltA();
  mfrc522.PCD_StopCrypto1();
}

/******************************************************************************/

MFRC522::StatusCode verificarClaveNueva(byte bloque)
{
  MFRC522::MIFARE_Key key;
  for (byte i = 0; i < 6; i++) key.keyByte[i] = finalDelSector[i];
  /*
     si key es la clave nueva
        retorna MFRC522::STATUS_OK
     si no
        retorna el error correspondiente
  */
  return mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A,
                                  bloque, &key, &(mfrc522.uid));
}

/******************************************************************************/

MFRC522::StatusCode tarjetaTieneClaveDeFabrica(byte bloque)
{
  MFRC522::MIFARE_Key key;
  for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF;
  /*
     si key es la clave de fábrica ( FF FF FF FF FF FF )
     retorna MFRC522::STATUS_OK para cambiarla por la clave nueva
  */
  return mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A,
                                  bloque, &key, &(mfrc522.uid));
}

/******************************************************************************/

MFRC522::StatusCode cambiarClaveDeFabrica(byte bloque)
{
  MFRC522::MIFARE_Key key;
  for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF;

  MFRC522::StatusCode retCambioClave;

  /* Serial.println(F("Autenticacion mediante key A..."));  */

  retCambioClave = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A,
                   bloque, &key, &(mfrc522.uid));
  if (retCambioClave != MFRC522::STATUS_OK) return retCambioClave;

  /* Escribir bloque */
  retCambioClave = mfrc522.MIFARE_Write(bloque, finalDelSector, 16);
  if (retCambioClave != MFRC522::STATUS_OK) return retCambioClave;

  return retCambioClave;
}

que genera esta salida cuando paso una tarjeta con la clave de fabrica:

Escribir datos personales en un PICC MIFARE
Tag ID: 41 5D 23 1A Tipo Tag: MIFARE 1KB

Cambiando clave de fabrica Timeout in communication.

Tag ID: 41 5D 23 1A Tipo Tag: MIFARE 1KB

Cambiando clave de fabrica **** Clave cambiada : Success.

pero genera esta salida cuando paso una tarjeta con la clave nueva:

Escribir datos personales en un PICC MIFARE
Tag ID: 41 5D 23 1A Tipo Tag: MIFARE 1KB

ERROR en la clave de fabrica :
Timeout in communication.

**** Verificando clave nueva : Timeout in communication.

Tag ID: 41 5D 23 1A Tipo Tag: MIFARE 1KB

y si le agrego un PCD_StopCrypto1 despues de cada autenticación como en este código:

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

//------------------------------------------------------------------------------
//#### MODULO RFID ####

#define MFRC522_RST_PIN       0
#define MFRC522_SS_PIN        5

/********************************/

#define CLV_NVA_0     0xAA
#define CLV_NVA_1     0xBB
#define CLV_NVA_2     0xCC
#define CLV_NVA_3     0xDD
#define CLV_NVA_4     0xEE
#define CLV_NVA_5     0xFF

/********************************/


MFRC522 mfrc522(MFRC522_SS_PIN, MFRC522_RST_PIN);

byte finalDelSector[18] = {CLV_NVA_0, CLV_NVA_1, CLV_NVA_2, CLV_NVA_3,
                           CLV_NVA_4, CLV_NVA_5, /* 6 primeros nueva clave */
                           0xFF, 0x7, 0x80, 0x69, /* 4 siguientes FF, 7, 80, 69 */
                           0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
                          }; /* 6 ultimos FF */
byte bloqueObjetivo = 31;

/******************************************************************************/

void setup()
{
  Serial.begin(115200);

  SPI.begin();
  mfrc522.PCD_Init();

  Serial.println(F("Escribir datos personales en un PICC MIFARE "));
}


/******************************************************************************/

void loop()
{
  if ( ! mfrc522.PICC_IsNewCardPresent() ) return;

  if ( ! mfrc522.PICC_ReadCardSerial() ) return;

  //----------------------------------------------------------------------------

  Serial.print(F("Tag ID:"));
  for (byte i = 0; i < mfrc522.uid.size; i++)
  {
    Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
    Serial.print(mfrc522.uid.uidByte[i], HEX);
  }
  Serial.print(F(" Tipo Tag: "));
  MFRC522::PICC_Type piccType = mfrc522.PICC_GetType(mfrc522.uid.sak);
  Serial.println(mfrc522.PICC_GetTypeName(piccType));
  Serial.println("");
  Serial.println("");

  //----------------------------------------------------------------------------

  MFRC522::StatusCode estClvFabrica = tarjetaTieneClaveDeFabrica(bloqueObjetivo);
  if ( estClvFabrica == MFRC522::STATUS_OK )
  {
    Serial.print("Cambiando clave de fabrica");
    MFRC522::StatusCode estadoCambioClave = cambiarClaveDeFabrica(bloqueObjetivo);
    if ( estadoCambioClave == MFRC522::STATUS_OK )
    {
      Serial.print("  **** Clave cambiada : ");
    }
    Serial.print("  ");
    Serial.println(mfrc522.GetStatusCodeName(estadoCambioClave));
  }
  else
  {
    Serial.println("ERROR en la clave de fabrica : ");
    Serial.println(mfrc522.GetStatusCodeName(estClvFabrica));
    
    Serial.println("");
    
    MFRC522::StatusCode estVerifClaveNueva;
    Serial.print("**** Verificando clave nueva : ");
    estVerifClaveNueva = verificarClaveNueva(bloqueObjetivo);
    Serial.println(mfrc522.GetStatusCodeName(estVerifClaveNueva));
  }

  //----------------------------------------------------------------------------

  Serial.println("");
  Serial.println("");
  
  mfrc522.PICC_HaltA();
  mfrc522.PCD_StopCrypto1();
}

/******************************************************************************/

MFRC522::StatusCode verificarClaveNueva(byte bloque)
{
  MFRC522::MIFARE_Key key;
  for (byte i = 0; i < 6; i++) key.keyByte[i] = finalDelSector[i];
  /*
     si key es la clave nueva
        retorna MFRC522::STATUS_OK
     si no
        retorna el error correspondiente
  */
  return mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A,
                                  bloque, &key, &(mfrc522.uid));

  mfrc522.PCD_StopCrypto1();
}

/******************************************************************************/

MFRC522::StatusCode tarjetaTieneClaveDeFabrica(byte bloque)
{
  MFRC522::MIFARE_Key key;
  for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF;
  /*
     si key es la clave de fábrica ( FF FF FF FF FF FF )
     retorna MFRC522::STATUS_OK para cambiarla por la clave nueva
  */
  return mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A,
                                  bloque, &key, &(mfrc522.uid));

  mfrc522.PCD_StopCrypto1();
}

/******************************************************************************/

MFRC522::StatusCode cambiarClaveDeFabrica(byte bloque)
{
  MFRC522::MIFARE_Key key;
  for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF;

  MFRC522::StatusCode retCambioClave;

  /* Serial.println(F("Autenticacion mediante key A..."));  */

  retCambioClave = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A,
                   bloque, &key, &(mfrc522.uid));
  if (retCambioClave != MFRC522::STATUS_OK) return retCambioClave;

  /* Escribir bloque */
  retCambioClave = mfrc522.MIFARE_Write(bloque, finalDelSector, 16);
  if (retCambioClave != MFRC522::STATUS_OK) return retCambioClave;

  mfrc522.PCD_StopCrypto1();

  return retCambioClave;
}

me genera esta salida:

Escribir datos personales en un PICC MIFARE
Tag ID: 41 5D 23 1A Tipo Tag: MIFARE 1KB

ERROR en la clave de fabrica :
Timeout in communication.

**** Verificando clave nueva : Timeout in communication.

¿me pueden ayudar con este tema?

muchas gracias,
saludos

aparentemente cuando algo sale mal con la tarjeta, por ej: si no se pudo autenticar, el módulo o la tarjeta (no se cual de los dos) corta toda comunicación, como si se hubiese retirado la tarjeta

para solucionarlo, agregué PICC_IsNewCardPresent y PICC_ReadCardSerial si no se pudo autenticar con la clave de fábrica

les dejo el código, fíjense al final de int verificarClaveDeFabrica(byte bloque), el último else

saludos,

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

//------------------------------------------------------------------------------
//#### MODULO RFID ####

#define MFRC522_RST_PIN       0
#define MFRC522_SS_PIN        5

/********************************/

#define CLV_NVA_0     0x20
#define CLV_NVA_1     0x90
#define CLV_NVA_2     0x30
#define CLV_NVA_3     0x16
#define CLV_NVA_4     0xD2
#define CLV_NVA_5     0xBC

/********************************/


MFRC522 mfrc522(MFRC522_SS_PIN, MFRC522_RST_PIN);

byte finalDelSector[18] = {CLV_NVA_0, CLV_NVA_1, CLV_NVA_2, CLV_NVA_3,
                           CLV_NVA_4, CLV_NVA_5, /* 6 primeros nueva clave */
                           0xFF, 0x7, 0x80, 0x69, /* 4 siguientes FF, 7, 80, 69 */
                           0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
                          }; /* 6 ultimos FF */
byte bloqueObjetivo = 31;

/******************************************************************************/

void setup()
{
  Serial.begin(115200);

  SPI.begin();
  mfrc522.PCD_Init();

  Serial.println(F("Escribir datos personales en un PICC MIFARE "));
}


/******************************************************************************/

void loop()
{
  if ( ! mfrc522.PICC_IsNewCardPresent() ) return;

  if ( ! mfrc522.PICC_ReadCardSerial() ) return;

  //----------------------------------------------------------------------------

  Serial.print(F("Tag ID:"));
  for (byte i = 0; i < mfrc522.uid.size; i++)
  {
    Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
    Serial.print(mfrc522.uid.uidByte[i], HEX);
  }
  Serial.print(F(" Tipo Tag: "));
  MFRC522::PICC_Type piccType = mfrc522.PICC_GetType(mfrc522.uid.sak);
  Serial.println(mfrc522.PICC_GetTypeName(piccType));
  Serial.println("");
  Serial.println("----------------------------------------------------------");
  Serial.println("");

  //----------------------------------------------------------------------------

  int ret = verificarClaveDeFabrica(bloqueObjetivo);
  Serial.println(ret, DEC);

  //----------------------------------------------------------------------------

  Serial.println("");
  Serial.println("");

  mfrc522.PICC_HaltA();
  mfrc522.PCD_StopCrypto1();
}

/******************************************************************************/
/*
 * -4   PICC_ReadCardSerial()
 * -3   PICC_IsNewCardPresent()
 * -2   ERROR al autenticarse con la nueva clave
 * -1   ERROR en la escritura del sector final con la clave nueva
 *  0   Autenticado con la nueva clave
*/
int verificarClaveDeFabrica(byte bloque)
{
  MFRC522::StatusCode estado;
  MFRC522::MIFARE_Key key;
  for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF;

  estado = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A,
                                    bloque, &key, &(mfrc522.uid));

  if ( estado == MFRC522::STATUS_OK )
  { /* se pudo autenticar con la clave de fabrica
       debe ser cambiada */
    Serial.println("## Autenticado con la clave de fabrica, cambiando...");
    estado = mfrc522.MIFARE_Write(bloque, finalDelSector, 16);
    if ( estado == MFRC522::STATUS_OK )
    {
      Serial.println("## Clave cambiada, autenticando con la nueva clave...");
      return autenticarConClaveNueva(bloque);
    }
    else
    {
      Serial.println("#### ERROR en la escritura del sector final con la clave nueva");
      Serial.println(mfrc522.GetStatusCodeName(estado));
      return -1;
    }
  }
  else
  {
    if ( ! mfrc522.PICC_IsNewCardPresent() ) return -3;
    if ( ! mfrc522.PICC_ReadCardSerial() ) return -4;
    Serial.println("## Clave de fabrica erronea, autenticando con la nueva clave...");
    return autenticarConClaveNueva(bloque);
  }
}

/******************************************************************************/

/*
   -2   ERROR al autenticarse con la nueva clave
    0   Autenticado con la nueva clave
*/
int autenticarConClaveNueva(byte bloque)
{
  MFRC522::StatusCode estado;
  MFRC522::MIFARE_Key key;
  
  key.keyByte[0] = CLV_NVA_0; key.keyByte[1] = CLV_NVA_1;
  key.keyByte[2] = CLV_NVA_2; key.keyByte[3] = CLV_NVA_3;
  key.keyByte[4] = CLV_NVA_4; key.keyByte[5] = CLV_NVA_5;
  
  estado = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A,
                                    bloque, &key, &(mfrc522.uid));
  if ( estado == MFRC522::STATUS_OK )
  {
    Serial.println("## Autenticado con la nueva clave");
    return 0;
  }
  else
  {
    Serial.println("#### ERROR al autenticarse con la nueva clave");
    Serial.println(mfrc522.GetStatusCodeName(estado));
    return -2;
  }
}

Lo resolviste de esa manera?

si, existe alguna manera más elegante o mejor?
gracias, saludos

No lo se, no tengo el hardware asi que imposible sugerirte algo.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.