Arduino und RFID sichern ein Computerprogramm ab

Die Möglichkeiten die man mit einem Arduino Board hat, sind schier unbegrenzt. Lediglich die eigene Kreativität setzt uns Grenzen. In einem kleinen Projekt möchte das Electastic Team als Ideengeber dienen und aufzeigen, in welche Richtung man gehen könnte. Dabei stellen wir einen Rahmen vor, von dem ausgehend, man eine Vielzahl von Projekten umsetzen kann. Ein paar Tipps dazu findest Du am Ende des Artikels.

Wir bringen unserem Arduino bei, auf so genannte RFID Chips zu reagieren und mit einem Programm auf dem Rechner zu kommunizieren. Das Programm auf dem Rechner reagiert auf den RFID Chip und gibt Zugriff auf bestimmte Programmfunktionen frei.

Wir unterteilen das Projekt in verschiedene Phasen.

Zunächst einmal kümmern wir uns um die benötigten Bauteile. Anschließend verschalten wird die Bauteile und bringen das Ganze „zum Fliegen“. Wenn unser Arduino – RFID-Reader Gespann auf RFID Tags in der gewünschten Weise reagiert, kümmern wir uns um die Anbindung an ein Computerprogramm.

Benötigte Bauteile für den Arduino RFID-Reader

Arduino Board

Man benötigt natürlich den Arduino selbst!

Keine Produkte gefunden.

Netzteil für Arduino (optional)

Wenn Du den Arduino über eine externe Spannungsquelle versorgen möchtest, ist ein passendes Netzteil eine gute Idee! Für dieses Projekt ist dies allerdings nicht erforderlich.

Netzteil für Arduino Uno Rev. 3 Microcontroller Board
  • nicht für Idena CD Player
  • Diese 9V hochwertige Netzteil ist kompatibel mit Arduino Uno Platine
  • Eingang: 100-240V | Ausgang: 9V 1A,Länge: 150cm
  • Steckergröße: 5.5mm/2.1mm
  • Garantie: 1 Jahr ab Kaufdatum

RFID Reader

Der von uns eingesetzte RFID Reader (RFID RC522) arbeitet bei 13,56 MHz und unterstützt ISO14443A/Mifare®. Wer RFID Chips kaufen möchte, muss dies berücksichtigen. Es werden MIFARE® Classic Produkte unterstützt. Die passenden RFID Tags sind günstig und in unterschiedlichster Form verfügbar.

RFID Reader für Arduino
  • ✅ LIEFERUMFANG - RFID-RC522 Modul, S50 Karte (13,56MHz), S50 Schlüsselanhänger (13,56MHz), Stiftleisten
  • ✅ SCHNELLER EINSTIEG - durch bereits verfügbare Bibliotheken und SPI Schnittstelle
  • ✅ ANWENDUNGEN - z.B. für die Entwicklung von Zugriffskontrollen, elektronischen Türschlösser oder Terminals zur Zeiterfassung
  • ✅ UNTERSTÜTZTE FORMATE - S50, S70 Ultralight, Pro
  • ✅ Dieses Produkt enthält ein E-Book, das nützliche Informationen über den Beginn Ihres Projekts enthält, es hilft bei einer schnellen Einrichtung und spart Zeit beim Konfigurationsprozess. Wir bieten eine Reihe von Anwendungsbeispielen, vollständige Installationsanleitungen und Bibliotheken.

Neben der RFID 13,56 MHz Technik gibt es noch die 125 kHz (LF)-Technik und die 868 MHz UHF (passiv)-Technik.

RFID Frequenz
Merke: Je höher die Frequenz, desto größer die Reichweite. Gleichzeitig steigt mit der Frequenz der Einfluss von Störfaktoren durch Reflexionen durch zum Beispiel Wasser oder Metall.

Zubehör

Kabel und Breadboard

Was darf nicht fehlen? Klar, Kabel braucht der Elektronikfreak immer und Breadboards auch.

RFID Tags (optional)

RFID Tags gibt es in vielen Ausführungen zu kaufen. Bevor Du einen 100er Pack bestellst, teste zunächst, ob der von Dir eingesetzte RFID Reader mit den Tags zusammenarbeitet. Nicht alle Tags sind kompatibel! Der oben verlinkte Reader bringt einen kompatiblen RFID Tag mit.

Keine Produkte gefunden.

Arduino mit RFID Reader verschalten

Unser fertiges Konstrukt sieht wie folgt aus:

Verschaltung RFID Reader RC522

Verschaltung RFID Reader RC522

PIN Belegung

Arduino Uno

RC522-READER

10

SDA

13

SCK

11

MOSI

12

MISO

IRQ

GND

GND

9

RST

3,3V

3,3V

RFID Tag mit Arduino erkennen

Jetzt spätestens benötigst Du die Arduino IDE.

RFID Bibliothek einspielen

Starte die IDE und hole Dir die Bibliothek für den RFID Reader. Die fertige Bibliothek erspart uns endlos Zeit. Mit ihr können wir sofort loslegen.

RFID Bibliothek einbinden (1)

RFID Bibliothek einbinden (1)

RFID Bibliothek einbinden (2)

RFID Bibliothek einbinden (2)

Ardunino IDE richtig einstellen

Starte nach der Installation die Arduino  IDE zur Sicherheit neu. Schließe dann den Arduino mit dem USB Kabel an den Rechner an. Achte in der Arduino IDE darauf, dass Du das korrekte Board eingestellt hast.

Korrektes Board in der Arduino IDE

Korrektes Board in der Arduino IDE

Ebenso wichtig ist es, den COM Port des Arduino Boards richtig zu wählen. Über diesen Port wird mit dem Arduino kommuniziert.

COM Port Arduino

COM Port Arduino

Beispiel Sketch für den RFID Reader

An dieser Stelle prüfen wir, ob unser Gespann aus Arduino und dem RFID Reader funktioniert. Unter Datei – Beispiele sollte jetzt ein Eintrag MFRC522 stehen.

MFRC522

MFRC522

Wir laden den Sketch ReadNUID. Sie Dir unbedingt den Kommentar im Sketch an. Dort ist die erforderliche PIN Belegung für die Verschaltung angegeben. Stelle sicher, dass die Belegung bei Dir korrekt ist.

/*
 * Typical pin layout used:
 * – ---------------------------------------------------------------------------------------
 *             MFRC522      Arduino       Arduino   Arduino    Arduino          Arduino
 *             Reader/PCD   Uno/101       Mega      Nano v3    Leonardo/Micro   Pro Micro
 * Signal      Pin          Pin           Pin       Pin        Pin              Pin
 * – ---------------------------------------------------------------------------------------
 * 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
 */

Bevor wir den Sketch an unseren Arduino übertragen, starten wir den über Werkzeuge, den seriellen Monitor!

Nochmals zurück zum Sketch. Dort findest Du in der Setup Routine den Befehl  Serial.begin(9600);

Damit starten wir die serielle Kommunikation mit einer Baudrate von 9600.

Baudrate - Serielle Schnittstelle
Die Baudrate ist beim Austausch von Daten über die serielle Schnittstelle von enormer Bedeutung. Sender und Empfänger von Daten müssen die gleiche Baudrate verwenden. Werden unterschiedliche Raten verwendet, dann wird entweder nichts oder, oft nicht schlimmer, Datensalat übertragen! Eine üble Fehlerquelle!

Und genau diese Baudrate müssen wir, falls nicht bereits geschehen, im seriellen Monitor einstellen. Wenn Du möchtest, stelle die Baudrate einfach einmal um. Du wirst sehen, dass Du eben nichts Sinnvolles mehr siehst 😉

Baudrate muss bei Sender und Empfänger übereinstimmen

Baudrate muss bei Sender und Empfänger übereinstimmen

Jetzt übertragen wir den Sketch an den Arduino. Wenn alles gut geht, keine Fehlerhinweise, dann ist der RFID Reader bereit, auf unseren RFID Tag zu reagieren. Hole den seriellen Monitor in den Vordergrund. Dort solltes Du bereits eine Ausgabe wie folgt sehen:

 

RFID-Reader-Feedback

RFID-Reader-Feedback

Halte jetzt den RFID Tag an den Reader. Du solltest eine Ausgabe ähnlich der folgenden sehen.

RFID Tag NUID

RFID-Tag-NUID

Datenaustausch PC – Arduino

Wir erstellen jetzt ein ganz minimalistisches Programm, welches auf einen RFID Tag reagiert. Wir möchten, dass der Arduino auf einen RFID Tag regiert, die UID ausliest und diese an ein Programm auf den PC sendet. Das Programm arbeitet dann mit dieser Information weiter und gibt, sofern der RFID Tag mit einer bestimmten Berechtigung einher geht, spezielle Daten oder Funktionen Preis.

Arduino Anteil

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

#define SS_PIN 10
#define RST_PIN 9

MFRC522 rfid(SS_PIN, RST_PIN); // rfid-Objekt


/**
 * Hilfsroutine ByteArray nach Hex 
 */
void printHex(byte *buffer, byte bufferSize) {
  for (byte i = 0; i < bufferSize; i++) {
    Serial.print(buffer[i] < 0x10 ? "0" : "");
    Serial.print(buffer[i], HEX);
  }
}

void setup() {  
  Serial.begin(9600); //Baudrate auf 9600 stellen und serielle Kommunitaion starten
  while (!Serial); //Warten bis der Port geöffnet ist
  SPI.begin(); // Initialisiere SPI bus 
  rfid.PCD_Init(); // Init MFRC522 

}

void loop() {
  //Neuen rfid Tag erkannt?
  if ( ! rfid.PICC_IsNewCardPresent())
    return;

  //Wurde die UID ausgelesen?
  if ( ! rfid.PICC_ReadCardSerial())
    return;
    
  //Tag Typ ermitteln und prüfen, ob der Tag Typ unterrstützt wird
  MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);
  
  
  if (piccType != MFRC522::PICC_TYPE_MIFARE_MINI &&  
    piccType != MFRC522::PICC_TYPE_MIFARE_1K &&
    piccType != MFRC522::PICC_TYPE_MIFARE_4K &&
    //MIFARE Ultralight or Ultralight C - Damit funkioniert unser Armband von oben
    //Das Armband liefert eine 7 Byte UID 
    piccType != MFRC522::PICC_TYPE_MIFARE_UL) 
   {
    //Fehler falscher Kartentyp
    return;
  }
  //An dieser Stelle wissen wir, dass der Typ des RFID Tags unterstützt wird
  //Die UID liegt vor, wir erstellen unser Kommando 
   Serial.print(F("cs:"));//Header für unsere Nachricht
   printHex(rfid.uid.uidByte, rfid.uid.size);//Die UID Hex-codiert
   Serial.print(F(":ce"));//Footer für unsere Nachricht
   Serial.println();//Und Zeilenumbruch

  // PICC anhalten
  rfid.PICC_HaltA();
  delay(2000);//zwei Sekunden warten
}

Was macht der Arduino Sketch?

Im Setup Anteil wird die serielle Schnittstelle initialisiert. Die Baudrate wird auf 9600 eingestellt. Mit SPI.begin() wird der SPI Bus initialisiert und schließlich unser rfid Objekt.

In der Loop Routine wird auf RFID Tags reagiert. Werden RFID Tags erkannt, wird geprüft, ob diese unterstützt werden. Falls es sich um einen unterstützten RFID Tag handelt, lesen wird die Kennung (UID) aus und erstellen uns eine Nachricht.

Die Nachricht wird als String über die serielle Schnittstelle übertragen. Dabei senden wir einen Header (cs:) und einen Footer (:ce) um aus unserem Programm heraus den Anfang und das Ende einer Nachricht zu erkennen. Hält man einen RFID Tag an den Reader, wird im seriellen Monitor etwas wie cs:86CC7AA1:ce angezeigt.

Delphi Programm zur Kommunikation mit dem Arduino

In der Wahl der Programmiersprache ist man selbstverständlich frei. Wichtig ist, dass man über die serielle Schnittstelle Daten empfangen (und senden) kann. Per Java Script geht das zum Beispiel nicht. Das Projekt sollte mit der Delphi Starter Edition machbar sein.

Für Delphi gibt es bereits eine vorgefertigte Komponentensammlung die uns die Kommunikation über die serielle Schnittstelle sehr einfach macht. Unter Tools den GetIt-Package-Manager aufrufen und als Suchbegriff asyncpro eingeben.

AsyncPro

AsyncPro

Nach der Installation können wir auf die benötigten Komponenten zugreifen. Wir ziehen uns eine TApdComPort Komponente und eine TApdDataPacket auf das Formular.

var
  ApdComPort1: TApdComPort;

  ApdComPort1 := TApdComPort.Create(Self);

  with ApdComPort1 do
  begin
    Name := 'ApdComPort1';
    Baud := 9600;
    AutoOpen := False;
    TraceName := 'APRO.TRC';
    LogName := 'APRO.LOG';
  end;

Jetzt müssen wir unbedingt bei ApdComPort1 die Baudrate auf 9600 stellen. Falls die Portnummer aus der Arduino IDE direkt verwendet werden soll, kann man diese unter ComNumber eintragen und PromptForPort auf false stellen. Ansonsten kann man PromptForPort auf true stellen, es erscheint dann beim Zugriff auf die serielle Schnittstelle ein Dialog in dem man den Port wählen kann.

var
  ApdDataPacket1: TApdDataPacket;

  ApdDataPacket1 := TApdDataPacket.Create(Self);

  with ApdDataPacket1 do
  begin
    Name := 'ApdDataPacket1';
    Enabled := True;
    IncludeStrings:= False;
    EndCond := [ecString];
    StartString := 'cs:';
    EndString := ':ce';
    ComPort := ApdComPort1;
    PacketSize := 0;
  end;

ApdDataPacket1 wird über ComPort mit der Komponente ApdComPort1 verknüpft. Wir übertragen vom Arduino eine Nachricht mit Header und Footer. Entsprechend tragen wir bei ApdDataPacket1 als StartCond scString und den Header cs: ein. Bei EndCond aktivieren wir ecString und tragen bei EndString  :ce ein.

Jetzt haben wir es fast geschafft. Einen Button auf das Formular ablegen und Name btnStartSerialCom vergeben. Im OnClick initiieren wir mit

APDComPort1.Open := True;

die serielle Kommunikation. Ist der Port geöffnet, reagieren wir im OnStringPacket Ereignis  von ApdDataPacket1 auf eingehende Tag Nachrichten. Weil wir die Eigenschaft IncludeStrings auf false gesetzt haben, erhalten wir die reine UID als HEX String. Ganz nach dem Motto, Beispiele so einfach wie möglich, haben wir die UID unseres RFIT Tags als Konstante im Programm abgelegt.

In OnStringPacket vergleichen wir die eingelesene mit der, die die gesperrte Funktion freigibt. Falls der Tag die Freigabeberechtigung besitzt, setzen wir die Enabled Eigenschaft der Schaltfläche  btnPrivFunc auf true. Gleichzeitig starten wir einen Timer tmrReAuth, der nach 10 Sekunden die Schaltfläche wieder sperrt und erneut nach dem Tag verlangt.

Im Ganzen sieht die Anwendung jetzt so aus:

RFID-Reader-Delphi

RFID-Reader-Delphi

unit uRFIDReaderMain;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, AdPacket, OoMisc, AdPort,
  Vcl.ExtCtrls;

type
  TfmRFIDReaderArduino = class(TForm)
    ApdComPort1: TApdComPort;
    ApdDataPacket1: TApdDataPacket;
    btnStartSerialCom: TButton;
    btnPrivFunc: TButton;
    mmoLog: TMemo;
    tmrReAuth: TTimer;
    procedure ApdComPort1PortClose(Sender: TObject);
    procedure ApdComPort1PortOpen(Sender: TObject);
    procedure ApdDataPacket1StringPacket(Sender: TObject; Data: AnsiString);
    procedure btnStartSerialComClick(Sender: TObject);
    procedure tmrReAuthTimer(Sender: TObject);
  private
    procedure log(const aLogString: string);
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  fmRFIDReaderArduino: TfmRFIDReaderArduino;

const

  cTagID = '86CC7AA1';//UID des RFID Tags der Funktion freischaltet
                      //In der Praxis würde man die UID natürlich nicht als Konstante im Programm speichern!!!

implementation

{$R *.dfm}

procedure TfmRFIDReaderArduino.ApdComPort1PortClose(Sender: TObject);
begin
     Log('Port Close');
end;

procedure TfmRFIDReaderArduino.log(const aLogString:string);
begin
  if not Application.Terminated then
     mmolog.Lines.add(aLogstring);
end;


procedure TfmRFIDReaderArduino.ApdComPort1PortOpen(Sender: TObject);
begin
  Log('Warte auf RFID Tags');
end;

procedure TfmRFIDReaderArduino.ApdDataPacket1StringPacket(Sender: TObject; Data: AnsiString);
begin
   if Data = cTagID then
   begin
     btnPrivFunc.Enabled := True;
     Log('RFID Tag schaltet privilegierte Funktion frei');
     tmrReAuth.Enabled:= True;
   end;

   Log(Format('Eingehende Daten: %s',[data]));

end;

procedure TfmRFIDReaderArduino.btnStartSerialComClick(Sender: TObject);
begin
  try
     APDComPort1.Open := True;

  except

  end;
end;

procedure TfmRFIDReaderArduino.tmrReAuthTimer(Sender: TObject);
begin
    tmrReAuth.Enabled := False;
    btnPrivFunc.Enabled := False;
    Log('Privilegierte Funktion neu freischalten');
end;

end.

 

Delphi Kommunikation mit Arduino über Serielle Schnittstelle (414 Downloads)

Anmerkung zum Programm

Das Programm zeigt natürlich nur das prinzipielle Vorgehen und hat in der Form keinerlei praktischen Nutzen. Die Idee kann man aber sehr einfach in ein bestehendes Projekt übernehmen. Wesentlich in diesem Zusammenhang ist die Funktion ApdDataPacket1StringPacket in der Nachrichten von unserem Arduino eingehen.

Protokoll definieren

Die Nachricht ist nach dem Prinzip Header – Inhalt – Footer aufgebaut. Die  ApdDataPacket1StringPacket Routine liefert uns den blanken Inhalt, bereinigt von Header und Footer. In einem größeren Projekt, in dem man eventuell unterschiedliche Nachrichten erhält, empfiehlt es sich, Zeit in die Gestaltung der Nachrichten zu investieren.

Der eigentliche Inhalt, also der Anteil zwischen Header und Footer, kann nach einem speziellen festzulegenden Prinzip aufgebaut sein. Man baut sich auf diese Art ein Protokoll auf.

cs:99:Fehlerhafter Tag Typ:cse

cs:1:UID:cse

Wären Beispiele. Man trennt die Anteile des in ApdDataPacket1StringPacket erhaltenen Strings und parst entsprechend. So können wir jetzt auch Fehlermeldungen an unser Delphi Programm senden.

Daten an Arduino senden

Die serielle Kommunikation ist natürlich keine Einbahnstraße. Selbstverständlich kann man auch von Delphi aus Daten an den Arduino senden. Konkret auf AsyncPro bezogen funktioniert dies mit  ApdComPort1.PutString(aCmd); aCmd ist dabei die zu übertragende Nachricht, die nach einem festzulegenden Protokoll aufzubauen ist. Im Arduino Sketch kann man in der Loop-Routine die Daten einlesen, auswerten und darauf reagieren. Ebenfalls kein Hexenwerk.

 if (Serial.available() > 0) //Es gibt etwas einzulesen
 {  

  String aCommand = Serial.readString();//Wir lesen von Delphi übertragenen String ein  
  
  if (aCommand.length() > 0)//evtl. Timeout!
  {
    //Hier Kommando auswerten und entsprechend reagieren
  }
  }

Zur Kommunikation zwischen PC und Arduino bzw., etwas universeller ausgedrückt, zwischen einem Device und dem Arduino muss man auch nicht zwingend die serielle Schnittstelle verwenden. Man denke an Ethernet, Wifi oder Bluetooth. Damit kann man in Windeseile auch auch eine App auf einem Tablet oder einem SmartPhone mit dem Arduino – RFID Reader verknüpfen.

Sicherheit der RFID Lösung

Absolute Sicherheit erreichen wir nie. Daher müssen wir wissen, wie schützenswert das ist, was wir absichern möchten. Für den Gartenschuppen mit Spaten und Spitzhacke genügt ein billiges Vorhängeschloss. Unsere Haustür hingegen sichern wir bereits mit einem ordentlichen Schloss ab. Die oben vorgestellte  Lösung wäre eher etwas für den Schuppen im Garten. Mit ein paar Kniffen, kann man die Sicherheit allerdings bereits drastisch erhöhen.

Sicherheitslücken RFID

Ein paar Anmerkungen zu diesem weiten Themenfeld. Die UID eines RFID Tags ist sagenhafte 4 Byte lang. 4 Byte sind 32 BIT mit denen man 2^32 = 4.294.967.296 verschiedene UIDs erzeugen kann. 4 Milliarden hört sich toll an, ist allerdings nicht die Welt 😉

Das schicke RFID Armband  von oben hat übrigens eine 7 Byte lange UID und ist vom Typ MIFARE Ultralight. Damit kann man tatsächlich von eindeutigen Kennern für die RFID Tags ausgehen. 7 * 8 = 56. Damit lassen sich immerhin 2^56 verschiedene UIDs generieren.

Man denke an ein Arduino Sketch, welches quasi mittels Brute Force alle möglichen Varianten der UID in den Com Port „flutet“.

Die UID eines RFID Tags kann ausgelesen und mit allen Daten kopiert werden. Aber nicht nur von uns. Man stelle sich die Frage, warum es Hüllen für den deutschen Reisepass gibt. Die größte Gefahr besteht also darin, dass die RFID-Tags kopieren werden können!

Die Kommunikation zwischen Arduino und PC über die serielle Schnittstelle ist nicht abgesichert. Es gibt Com Port Sniffer, mit denen man die Kommunikation überwachen kann und den Aufbau von Protokollen analysieren kann. Das wäre allerdings schon hohe Schule und in den meisten Fällen muss man sich um derartige Absicherungen nicht kümmern.

Niemals die UID als Schlüssel für eine Verschlüsselung einsetzen! Die UID ist mit maximal 56 BIT viel zu kurz, leicht ausles- und kopierbar!

Wie kann man die Sicherheit erhöhen?

In der mit dem Arduino kommunizierenden Anwendung sollte man eine Zeitsperre nach jedem Empfang einer Nachricht einbauen, die einen neuen Tag meldet. Man verhindert so das Fluten der Lösung durch zum Beispiel einen Sketch der per Brute Force alle möglichen UIDs sendet.

RFID Tags können mehr. Viele RFID Tags stellen Speicher zur Verfügung, der beschrieben und natürlich ausgelesen werden kann. Man kann sich ein Verwaltungsprogramm schreiben, in dem man dann individuelle Werte in diese Speicher schreibt und später ausliest. Sieh Dir das Beispiel für MFRC522 mit dem Namen ReadAndWrite an!

Zum Abschluss sei angemerkt, dass die Karten/Tags Verschlüsselung einsetzen, die seit 2008 als unsicher gelten. Das eingesetzte Crypto-1 Verfahren zur Verschlüsselung der Kommunikation Tag-Reader ist nicht sicher.

Allerdings gibt es trotz dieser Unsicherheiten genügend Anwendungsfelder, in denen man obige Hardware, die zudem unschlagbar günstig ist, einsetzen kann.

Link: https://de.wikipedia.org/wiki/Mifare


Bildnachweis (Titelbild):
Stockfoto-ID: 64329277
Copyright: Light Emotions

Letzte Aktualisierung am 14.01.2023 / Affiliate Links / Bilder von der Amazon Product Advertising API

Das könnte dich auch interessieren …

Zum Anfang