Forum / MIFARE and NFC Reader IC`s / RFID Mifare writter/reader with CR038
-
Hi everyone !
I try to read and write on RFID card with an arduino nano and a RFID reader the CR038 in Mifare Protocol.
I use tutorial and information from this website :
https://tutorial.cytron.io/2013/11/06/interface-mifare-readerwriter-arduino/
I can set on and off leds on my module, I can get serial number of my module, I can get the NUID(detect a tag) but I can't authenticate my block ....
My code block when I wait a answer from the CR038 when I ask an authentification...
I know my key A is "0x4D,0x49,0x46,0x41,0x52,0x45".
my hexa command is :
char AUTHEN_SEC0[] = {0xAA,0xBB,0x0D,0x00,0x00,0x00,0x07,0x02,0x60,0x00,0x4D,0x49,0x46,0x41,0x52,0x45, 0x65}; //access to block 0
char AUTHEN_SEC1[] = {0xAA,0xBB,0x0D,0x00,0x00,0x00,0x07,0x02,0x60,0x04,0x4D,0x49,0x46,0x41,0x52,0x45, 0x61}; // access to block 4
but I think the problem came from my last byte command , the XOR one. I don't understand hox to calculate this one...
my code:
#include
/*****MiFare commands*****/
char LED_ON[] = {0xAA,0xBB,0x06,0x00,0x00,0x00,0x07,0x01,0x01,0x07}; //Command to turn on MiFare module onboard LED
char LED_OFF[] = {0xAA,0xBB,0x06,0x00,0x00,0x00,0x07,0x01,0x00,0x06}; //Command to turn off MiFare module onboard LED
char ANTENNA_ON[] = {0xAA,0xBB,0x06,0x00,0x00,0x00,0x0C,0x01,0x01,0x0C}; //Command to turn off MiFare module onboard antenna
char READ_DEV[] = {0xAA,0xBB,0x05,0x00,0x00,0x00,0x03,0x01,0x02}; //Command to read MiFare module device number
char CARD_REQ[] = {0xAA,0xBB,0x06,0x00,0x00,0x00,0x01,0x02,0x52,0x51}; //Command to request card type of MiFare card
char ANTI_COL[] = {0xAA,0xBB,0x05,0x00,0x00,0x00,0x02,02,00}; //Command for anti-collision
char CARD_SEL[] = {0xAA,0xBB,0x09,0x00,0x00,0x00,0x03,0x02,0x00,0x00,0x00,0x00,0x00}; //Command to select specific MiFare card for access
//Byte 0 to byte 12 of this command is initialized with 0x00, since have to obtain the NUID of the MiFare card scanned
//Byte 8 to byte 11 of this command will filled with NUID (started with the lowest byte) of the MiFare card desire to access
//Byte 12 of this command is checksum from byte 4 to byte 11 of this command may change for NUID different from that in this case
//This array will be filled during the subroutine of the get_nuid() in this program
char AUTHEN_SEC0[] = {0xAA,0xBB,0x0D,0x00,0x00,0x00,0x07,0x02,0x60,0x00,0x4D,0x49,0x46,0x41,0x52,0x45, 0x65}; //Command to authenticate Sector 0 in memory of MiFare card
char AUTHEN_SEC1[] = {0xAA,0xBB,0x0D,0x00,0x00,0x00,0x07,0x02,0x60,0x04,0x4D,0x49,0x46,0x41,0x52,0x45, 0x61}; //Command to authenticate Sector 1 in memory of MiFare card
char READ_0[] = {0xAA,0xBB,0x06,0x00,0x00,0x00,0x08,0x02,0x00,0x0A}; //Command to read Block 0 (manufacturer block in Sector 0) in memory of MiFare card
char WRITE_4[] = {0xAA,0xBB,0x16,0x00,0x00,0x00,0x09,0x02,0x04,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x0F}; //Command to write data into Block 4 (in Sector 1) in memory of MiFare card
//Data to be written (started with the lowest byte) is from byte 9 to 24,
//total of 16 bytes data
//Data is 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A
//0x0B,0x0C,0x0D,0x0E,0x0F in this case
//The last checksum byte of this command may change for data to written different from
//that in this case
char READ_4[] = {0xAA,0xBB,0x06,0x00,0x00,0x00,0x08,0x02,0x04,0x0E}; //Command to read data in Block 4 (in Sector 1) in memory of MiFare card
/*****************************/
unsigned char reply_buffer[26]; //Buffer to store data received from MiFare module when a certain command is sent (maximum is 26 bytes in this case)
unsigned char NUID[4]; //Array for storing NUID of a MiFare card
char mode = 0; //Variable storing current mode of the program
SoftwareSerial RFIDSerial(10, 11);
void setup()
{
Serial.begin(9600); //Initiallize UART serial communication with baudrate = 19200bps (default baudrate of MiFare module)
RFIDSerial.begin(19200);
Serial.print("MiFare Demo"); //Print welcome message "MiFare Demo" on LCD
}
void loop()
{
String answer;
while(1)
{
led_on();
Serial.print("reponse on :");
for (int i=0; i<sizeof(reply_buffer);i++) Serial.print(reply_buffer);
Serial.println("");
delay(1000);
led_off();
Serial.print("reponse off :");
for (int i=0; i<sizeof(reply_buffer) ;i++) Serial.print(reply_buffer);
Serial.println("");
delay(1000);
// read dev num ;
read_dev();
Serial.print("reponse read DEV :");
for (int i=0; i<sizeof(reply_buffer) ;i++) Serial.print(reply_buffer);
Serial.println("");
delay(1000);
// get NUID
get_nuid();
Serial.print("NUID :");
for (int i=0; i<sizeof(NUID) ;i++) Serial.print(NUID);
Serial.println("");
delay(1000);
/*
// read 0 ;
read_0();
Serial.print("reponse read 4 :");
for (int i=0; i<sizeof(reply_buffer) ;i++) Serial.print(reply_buffer);
Serial.println("");
delay(1000);
*/
// read 4 ;
read_4();
Serial.print("reponse read 4 :");
for (int i=0; i<sizeof(reply_buffer) ;i++) Serial.print(reply_buffer);
Serial.println("");
delay(1000);
}
}
///*********************************************************************************************************************//
//Turn on MiFare module LED subroutine
void led_on(void)
{
for(int i = 0; i<10; i++)
{
RFIDSerial.write(LED_ON);
}
for(int i = 0; i<10; i++)
{
while(!RFIDSerial.available());
reply_buffer = RFIDSerial.read();
}
}
//Turn on MiFare module LED subroutine
void led_off(void)
{
for(int i = 0; i<10; i++)
{
RFIDSerial.write(LED_OFF);
}
for(int i = 0; i<10; i++)
{
while(!RFIDSerial.available());
reply_buffer = RFIDSerial.read();
}
}
//Read MiFare device number subroutine
void read_dev(void)
{
for(int i = 0; i<9; i++)
{
RFIDSerial.write(READ_DEV);
}
for(int i = 0; i<12; i++)
{
while(!RFIDSerial.available());
reply_buffer = RFIDSerial.read();
}
}
//Turn on antenna of MiFare module subroutine
void antenna_on(void)
{
for(int i = 0; i<10; i++)
{
RFIDSerial.write(ANTENNA_ON);
}
for(int i = 0; i<10; i++)
{
while(!RFIDSerial.available());
reply_buffer = RFIDSerial.read();
}
}
//Request MiFare card type subroutine
void card_req(void)
{
for(int i = 0; i<10; i++)
{
RFIDSerial.write(CARD_REQ);
}
for(int i = 0; i<12; i++)
{
while(!RFIDSerial.available());
reply_buffer = RFIDSerial.read();
}
}
//Perform Anti-Collison subroutine
void anti_col(void)
{
for(int i = 0; i<9; i++)
{
RFIDSerial.write(ANTI_COL);
}
for(int i = 0; i<14; i++)
{
while(!RFIDSerial.available());
reply_buffer = RFIDSerial.read();
}
//Byte 9 to byte 12 of replied bytes contains NUID of the MiFare card
//Store them in NUID[] array
for(int i = 0; i<4; i++)
{
NUID = reply_buffer[9+i];
}
}
//Select MiFare card subroutine
void card_sel(void)
{
for(int i = 0; i<13; i++)
{
RFIDSerial.write(CARD_SEL);
}
for(int i = 0; i<11; i++)
{
while(!RFIDSerial.available());
reply_buffer = RFIDSerial.read();
}
}
//Authenticate Sector 0 in memory of MiFare card subroutine
void authen_sec0(void)
{
for(int i = 0; i<17; i++)
{
RFIDSerial.write(AUTHEN_SEC0);
}
for(int i = 0; i<10; i++)
{
while(!RFIDSerial.available());
reply_buffer = RFIDSerial.read();
}
}
//Authenticate Sector 1 in memory of MiFare card subroutine
void authen_sec1(void)
{
for(int i = 0; i<17; i++)
{
RFIDSerial.write(AUTHEN_SEC1);
}
for(int i = 0; i<10; i++)
{
while(!RFIDSerial.available());
reply_buffer = RFIDSerial.read();
}
}
//Read data from Block 0 (manufaturer block) in memory of MiFare card subroutine
void read_0 (void)
{
Serial.println("OK 1");
get_nuid();
Serial.println("OK 2");
card_sel(); //Select MiFare card
Serial.println("OK 3");
authen_sec0(); //Authenticate Sector 0 in memory of MiFare card
for(int i = 0; i<10; i++)
{
RFIDSerial.write(READ_0);
}
for(int i = 0; i<26; i++)
{
while(!RFIDSerial.available());
reply_buffer = RFIDSerial.read();
}
}
//Read data from Block 4 in memory of MiFare card subroutine
void read_4(void)
{
Serial.println("OK 1");
get_nuid();
Serial.println("OK 2");
card_sel(); //Select MiFare card
Serial.println("OK 3");
authen_sec1(); //Authenticate Sector 0 in memory of MiFare card
Serial.println("OK 4");
for(int i = 0; i<10; i++)
{
RFIDSerial.write(READ_4);
}
for(int i = 0; i<26; i++)
{
while(!RFIDSerial.available());
reply_buffer = RFIDSerial.read();
}
}
//Write data into from Block 4 in memory of MiFare card subroutine
void write_4(void)
{
get_nuid();
card_sel(); //Select MiFare card
authen_sec1(); //Authenticate Sector 0 in memory of MiFare card
for(int i = 0; i<26; i++)
{
RFIDSerial.write(WRITE_4);
}
for(int i = 0; i<10; i++)
{
while(!RFIDSerial.available());
reply_buffer = RFIDSerial.read();
}
}
//Get NUID of MiFare card subroutine
void get_nuid(void)
{
unsigned char xor_temp = 0;
antenna_on(); //On the MiFare module onboard antenna
card_req(); //Request card type of MiFare card
anti_col(); //Perform anti-collision
for(int i = 0; i<4; i++) //Fill up byte 8 to byte 11 of CARD_SEL[] with NUID
{
CARD_SEL = NUID;
}
for(int i = 0; i<8; i++) //Calculate the checksum of byte 4 to byte 11 of the CARD_SEL[]
{
xor_temp ^= CARD_SEL[4+i];
}
CARD_SEL[12] = xor_temp; //Fill the checksum in byte 12 of CARD_SEL[]
}
Can you help me ?
Do you have any idea to help me ?
Du you already work with the CR038 or another RFID mifare serial reader ?
Thanks !
+ 0 | - 0
Hi Jean-Yves,
I do not know the “CR038 reader”. But you will find a user manual if you analyze the link. Did you read page 30 of the manual? There is an example of how to authenticate. For a blank card both keys A and B are FFFFFFFFFFFF. If your key is different, then you changed the keys previously?
One recommendation: please be careful when changing a key. The access permission bits are also in the sector trailer and you should not overwrite theses bytes. It exists access permission bit combinations where you can make the block/sector inaccessible! So, read always the current values back and insert it in the new data block.
As I understand the user manual correctly, the XOR byte is the checksum of the bytes of “Node ID”, “Function Code” and “Data”. It is a simple exclusive-or operation.
The TapLinx team
+ 0 | - 0
-
AuthorPosts
Viewing 2 posts - 1 through 2 (of 2 total)
You must be logged in to reply to this topic.