RFID Mifare writter/reader with CR038

Forum / MIFARE and NFC Reader IC`s / RFID Mifare writter/reader with CR038

  • 10. December 2019 at 16:30
    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

    Re: RFID Mifare writter/reader with CR038

    11. December 2019 at 10:55
    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
Viewing 2 posts - 1 through 2 (of 2 total)

You must be logged in to reply to this topic.