RFID Arduino-val és Mifare RC522 olvasóval/kártyával

2019-02-24

 

Manapság az ember a nap mint nap használ elektonikus azonosító rendszereket, elektronikus zárakat. Szállítótól függően, nagyjából 1-2 USD-ért lehet rendelni az alábbi olvasó/iróból+ egy kártyából+ egy tag-ből álló készletet, amit például egy Arduino-hoz kapcsolva tudunk használni.

Az eszköz hozzávetőleg úgy működik, hogy a panelen lévő RC-522 chip, a panelen vezetékezéssel kialakított tekercset 13,56MHz frekin gerjeszti. A kártyában, illetve a tag-ben szintén van egy tekercs, ha a kettőt egymáshoz közelítjük a fizika szabályai szerint áram indukálódik a kártyán lévő tekercsben, ami a kis benne lévő energiatakarékos chipnek elegendő is.

A kártya és az olvasó elkezd beszélgetni egymással. Engem csak elég korlátozottan érdekelt mit lehet az RC-522-vel csinálni, a neten részletesebben utána lehet olvasni. A technikát RFID (Radio Frekvency Identification) hívják, és elég sokféle létezik belőle, frekire, kommunikációra, kiolvasási távolságra, memória kapacitásra, processzorra. Amit most kipróbálunk, az 1 kB memóriával rendelkezik, amit lehet olvasni, meg írni is. Tulajdonképpen az első 4 byte a kártya sorszáma, ami kártyánként gyárilag különböző, de simán átírható. Így néz ki a kísérleti áramkör.

Így kötöttem össze a moduljaimat. Az alábbi rajzot nem én csináltam, a Google képkeresője dobta ki. A kártyaolvasót SPI soros vonalon keresztül lehet elérni, amit az Arduino kártyákon lévő AVR mikrokontrollerek hardwer-ből/alapból kezelnek. Ez jó, de annyiból probléma, hogy a különböző Arduino kártyákon más-más lábakra sikerült kivezetni, no hát olasz design... A programokba beírtam néhány Arduino esetében ezek melyik lábak, ha nekünk más típus van, egy kis utánajárással kibogozhatjuk.

Ha jól emlékszem ezt az RFID Library-t töltöttem le. Van hozzá mindenféle mintaprogram is, én a saját szájízem szerint kissé egyszerűsítettem őket. Az első program kiolvassa a kártya 4 byte-os UID azonosítóját és kiírja a soros monitorra. Könnyen továbbfejleszthető a program, hogy adott azonosítókat eltároljon, és ha azzal találkozik, mondjuk 3 másodpercre bekapcsoljon egy relét, kinyisson egy ajtót. A 4 byte 4.294.967.296 variációra ad lehetőséget. Úgy lehet a biztonságot megnövelni, hogy korlátozzuk a kiolvasások számát, mondjuk ismeretlen kártya esetében nem kell okvetlen riasztani, de 5 másodpercre letiltjuk az újabb beolvasást. Így téves olvasás esetén nem nagyon akadályozzuk meg a jogosult bejutását, de a próbálgatásos (brute force) feltöréshez szükséges időt majdnem 250.000 napra növeljük. Nyilván a teljes készlet végigpróblásához szükséges ennyi, ha mondjuk a feltesszük, hogy a teljes kódkészlet 1/10-ének végigpróbálása ereményhez vezet, akkor a betörőnknek elegendő 75 évet tölteni az ajtónk előtt. Az olcsóbb mechanikus zárak 3 csappal rendelkeznek, ha mondjuk csaponként 10 lehetőséggel számolunk, az 1.000 variációt ad. Okos betörő nem közlekedik 10 kilós kulcskarikával, nézelődjetek a Youtube-on. A drágább zárak mondjuk 5 csaposak, max. 100.000 variáció. A még drágább mechanikus zárak tudnak mester kulcsot kezelni, vagy átállíthatóak, tehát van egy kulcs amit az építőnek/szerelőknek adunk, amit az építkezés befejezése után le tudunk tiltani, és csak a már végleges kulcsunkkal tudjuk a zárat nyitni. Persze ilyenkor elég sok HUF-ot kell az üzletben hagynunk. Egy kis Ardinóval ezeket elég egyszerűen meg tudjuk csinál, sőt olyat is tudunk csinálni, hogy az egyik kártya csak nyissa az ajtót, a másik meg zárja. Olyat is lehet, hogy csak akkor nyíljon ki, ha két, vagy több kártyát alkalmazunk.



/******************************************************************************
*   Author       -  Kiraly Tibor
*                   http://www.tkiraaly.hu
*   Date         -  2019.02.24.
*   Chip         -  Ardiono, MRFC522 key reader
*   Compiler     -  Arduino IDE
*
*   MIFARE tag UID olvasasa
*   
*******************************************************************************
*
*    MFRC522 reader     Uno     Mega     Nano
*
*    RST                  9        5       D9
*    SDA(SS)             10       53      D10
*    MOSI                11       51      D11
*    MISO                12       50      D12
*    SCK                 13       52      D13
*
*******************************************************************************/


#include <MFRC522.h>


MFRC522 mfrc522( 10, 9);                         // SDA (SS), RST
MFRC522::MIFARE_Key key;


void setup()
{
   Serial.begin( 9600);
   SPI.begin();
   mfrc522.PCD_Init();
}


void loop()
{
   if ( mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial())
   {
      Serial.print( F( "Card UID:"));
      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.println();
   }
   else delay( 50);
}

A következő program kilistázza a kártya teljes 1 kbyte tartalmát.



/******************************************************************************
*   Author       -  Kiraly Tibor
*                   http://www.tkiraaly.hu
*   Date         -  2019.02.24.
*   Chip         -  Ardiono, MRFC522 key reader
*   Compiler     -  Arduino IDE
*
*   MIFARE tag tartalmanak kilistazasa
*   
*******************************************************************************
*
*    MFRC522 reader     Uno     Mega     Nano
*
*    RST                  9        5       D9
*    SDA(SS)             10       53      D10
*    MOSI                11       51      D11
*    MISO                12       50      D12
*    SCK                 13       52      D13
*
*******************************************************************************/


#include <MFRC522.h>


MFRC522 mfrc522( 10, 9);                         // SDA (SS), RST
MFRC522::MIFARE_Key key;


void setup()
{
   Serial.begin( 9600);
   SPI.begin();
   mfrc522.PCD_Init();
}


void loop()
{
   if ( mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial())
   {
     mfrc522.PICC_DumpToSerial(&(mfrc522.uid));
   }
   else delay( 50);
}

És végül itt van ez a harmadik program, ami megnehezíti az életünket, ezzel tetszőlegesen átírhatjuk a kártya UID azonosítóját. Szerintem az az igazság, hogy a mechanikus kulcsainkra is vigyáznunk kell, mert egy pillanat alatt lehet egy darab gyurmával lenyomatott venni róluk, és ugyan egy drágább berendezés meg némi gyakorlat is szükséges a lemásolásukhoz, de Youtube-on van fent olyan videó, hogy a srác csak egy darab papírra kopírozza át a kulcsot, amit ráragaszt egy kólás doboz lemezére, ollóval körbevágja, majd nyitja vele a zárat. Szerintem lehet, hogy kicsit macerásabb, de menne ez egy mobilos fotóról is. Ha tartani akarjuk a 75 évet, ne dugdossuk oda a kártyánkat mindeféle ismeretlen olvasóhoz, és mivel indulkció szükséges az elektronikus kulcsunk olvasásához/írásához, egy konzerv doboz lemezéből (az vas alpú, mágnesesen is árnyékol) hajtogassunk hozzá egy tokot, persze Kínából rendelhető is :). Azt tapasztaltam, hogy ez az olvasó, hozzávetőleg már 2cm távolságból eléri a kártyát. Tehát az író program.



/******************************************************************************
*   Author       -  Kiraly Tibor
*                   http://www.tkiraaly.hu
*   Date         -  2019.02.24.
*   Chip         -  Ardiono, MRFC522 key reader
*   Compiler     -  Arduino IDE
*
*   MIFARE tag UID atirasa
*   
*******************************************************************************
*
*    MFRC522 reader     Uno     Mega     Nano
*
*    RST                  9        5       D9
*    SDA(SS)             10       53      D10
*    MOSI                11       51      D11
*    MISO                12       50      D12
*    SCK                 13       52      D13
*
*******************************************************************************/


#include <MFRC522.h>


MFRC522 mfrc522( 10, 9);                                   // SDA (SS), RST
MFRC522::MIFARE_Key key;


byte new_uid[]= {0x12, 0xAD, 0xBE, 0xEF};


void setup()
{
   Serial.begin( 9600);
   SPI.begin();
   mfrc522.PCD_Init();
   // Prepare key - all keys are set to FFFFFFFFFFFFh at chip delivery from the factory.
   for ( byte i= 0; i < 6; i++) key.keyByte[ i]= 0xFF;
}


void loop() {
   if ( mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial())
   {
      Serial.print( F( "Card UID:"));
      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.println();
      if ( mfrc522.MIFARE_SetUid( new_uid, (byte)4, true)) Serial.println(F("Wrote new UID to card."));
      // Halt PICC and re-select it so DumpToSerial doesn't get confused
      mfrc522.PICC_HaltA();                                
      if ( ! mfrc522.PICC_IsNewCardPresent() || ! mfrc522.PICC_ReadCardSerial()) return;
      Serial.println( F( "New UID and contents:"));
      mfrc522.PICC_DumpToSerial(&(mfrc522.uid));
      delay( 2000);
   }  
   else delay( 50);
}

Ennyi az egész, itt a vége, fuss el véle.