ACS Containerisierung

Wir sind aktuell dabei unsere Fenster im Haus zu tauschen, was dazu führte, dass wir die Wand am eingangsbereich neu machen mussten (Holz weg, richtig dämmen, verputzen, streichen).
Da wir von Anfang an den RFID Leser im Eingangsbereich nur „provisorisch“ installiert haben, habe ich mir nun ein schickes Edelstahlgehäuse anfertigen lassen.

Lesereinbau vorher/nachher

Der Leser war wärend der Zeit der Renovierung leider offline.

Reboot mit Problemen

Der Server für das Zugangskontrollsystem ist das Letzte Artefakt, das ich noch nicht Containerisiert habe. Ich habe zwar dran gearbeitete, aber es gab hier noch diverse Probleme und die Integrationstests haben letztlich auch gefehlt. Ich wollte dies in aller Ruhe im sommerurlaub mal angehen. einen alten gebrauchten Testrechner habe ich dafür auch schon installiert gehabt, aber zu diesem Zeitpunkt war das System nicht einsatzbereit.

Auf dem alten Rechner den Docker zum Laufen bringen klappt nicht, da das darunterliegende OS (Ubuntu 16.04 LTS) zu alt war für die Java Requirements. D.b. ich muss den Server komplett neu aufsetzen und ein „Schwenk“ zu einem Container wäre nicht so schnell machbar gewesen. Wäre aber wünschenswert, dann hätte man den Container einfach hin und her schieben können um den Server in Ruhe auf den neuesten Stand updaten zu können.

Aber da der Rechner ja eh schon unten war (aufgrund der Renovierungsarbeiten) wollte ich zumindest mal ein OS Update fahren um die ganzen aktuell anstehenden Patches in Ubuntu 16.04 LTS nachzuziehen. Dabei kam dann der Rechner nach dem Reboot nicht wieder hoch. Scheinbar hat nach der langen Uptime der Rechner (den LESv2 der Thomas Krenn AG) den Reboot nicht verkraftet. Fakt ist, es kommt kein Bild, keine Ausgabe, nichts.

Tja, da half dann nur noch Flucht nach vorne. Ich habe den kleinen alten Testrechner ein Intel NUC) in den Serverschrank gepackt und frisch das OS draufgepackt. Erst ein Ubuntu Server 24.04 LTS, und, aufgrund von Betriebsproblemen (siehe unten), einen Tag später ein Ubuntu Server 22.04 LTS.
Danach binnen 2 Tagen den ACS-Server als Container so fertig bekommen, dass er läuft und alle Funktionalitäten wieder abdeckt (Mail, Pushover, MQTT, Relais ansteuern).
Zwischenzeitlich läuft der Server sogar nicht priviligiert als NonRoot im readonly Modus, das war schon seit Anfang an ein Problem, dass ich aber im Laufe der letzten Tage lösen konnte.

Ubuntu Server 24.04 LTS und HID Devices mit MCP2200 Chipsatz

Ubuntu Server 24.04 LTS ist das aktuelle Ubuntu Betriebssystem. Daher war es naheliegend dieses auch zu verwenden. Ich verwende für das Öffnen der Türe aktuell ein per USB angeschlossenes Relaisboard (USB Relay Module 4 Channels, for Home Automation – v2) der Firma Denkovi Assembly Electronics LTD. Das Board verwendet einen MCP2200 Chip und gibt sich als HiD Device aus. In der Regel wird im Linux unter den Devices dann ein /dev/hidraw0 und ein /dev/usb/hiddev0 angelegt. Leider funktionierte das nur bis Ubuntu Server 22.04 LTS. In Ubuntu Server 24.04 LTS hat sich das System strikt geweigert das Relais so anzulegen wie ich es erwartet hätte. Leider habe ich nach 1 Tag udev Regeln anlegen dann aufgegeben und bin auf Ubuntu Server 22.04 LTS gegangen.

Das Verhalten muss ich bei Zeiten mal genauer untersuchen bzw. wenn es mir hier nicht gelingt eine Lösung zu finden eine Relais Alternative zu suchen. Denkovi hat hier ja diverse alternative Möglichkeiten. Ggf. switche ich ja zu einer IP basierten Lösung.

ACS Komponenten im Container

Es laufen alle Komponenten des Zugangskontrollsystems nun auf einem Container. Damit werden Migrationsszenarien deutlich einfacher werden. Die Java Komponenten laufen in einem Debian Basiscontainer mit JRE21. Alle anderen Komponenten basieren auf schlanken Alpine Basiscontainern.

Alle Container sind mit Trivy sicherheitsüberprüft. Alle erkannten Vulnerabilities werden im Buildprozess dann entsprechend behandelt.

KomponenteBasisStand
ACS ServerDebian + JRE21Containerisiert
ACS ManagerAlpine + Nginx + PHP 8.1Containerisiert
ACS Tag ManagerDebian + JRE21Containerisiert
ACS Pushover ServiceAlpine + Python 3.11Containerisiert
REDISAlpineContainerisiert
LDAPAlpineContainerisiert
MQTTAlpineContainerisiert
ACS, Stand der Containerisierung

Offene Punkte

  1. Hausinterne DNS Probleme in den Griff bekommen: Entweder die Namensauflösung im ACS Server anpassen (herkömmlich statt den Ubunt Standard mit resolverd) oder, da es ein generelles Problem ist, hier mal eine echte Lösung finden.
  2. Erhöhung der RFID Leser Sensitivität, durch Durchbrechen des Faradayschen Käfigs. Leider schirmt der Edelstahlkasten die elektromagnetische Strahlung sehr ab. Ich versuche heute mla mit der Flex den Käfig mit einem Schnitt zu unterbrechen.
  3. RFID Leser mit Ubuntu Server 24.04 LTS ans Laufen bringen (siehe oben).

    FEIG OBID Firmware Version 2.8.131

    Nachdem nach dem letzten Firmware Update die KeepAlive Abbrüche nicht weggegangen sind habe ich dies der FEIG gemeldet. Da wohl ein anderer Kunde ein ähnliches Problem hat, hat die FEIG für diesen kunden den Netzwerk Stack in der Firmware optimiert. Die FEIG hat mir den Release Candidate für den Leser zum Test zur Verfügung gestellt.

    Das Flashen des Lesers mit dem RC ging, wie beim letzten mal, ohne Probleme und das Zugangskontrollsystem hat automatisch die Verbindung zum Leser wieder hergestellt.

    Mal sehen ob sich das Problem damit löst, ansonsten muss ich wohl Netzwerk Traces mitlaufen lassen um das Problem genauer zu Untersuchen.

    FEIG OBID Firmware Version 2.8.0

    Seit Nutzung des Lesers OBID ID CPR.50.10 der Firma FEIG ELECTRONIC GmbH habe ich mit Verbindungsabbrüchen in der Kommunikation des Lesers mit dem Server zu kämpfen. Das Ganze zeigt sich wie folgt:

    Im „Notifymode“ kann der Leser KeepAlive Requests an den Server senden. Dies habe ich auf eine recht knappe Zeit (5 Sekunden) eingestellt. In unregelmäßgien Abständen hat der Leser jedoch, ohne erfindlichen Grund, diese KeepAlive Requests eingestellt. Nach einigem Experimentieren habe ich hierfür einen Workaround gefunden.  Im Falle eines ausbleibens der Requests sende ich einen CPU Reset an den Leser. Dies hat meist geholfen.

    Leider hat sich das Ganze nach Einschalten der Verschlüsselten Verbindung verschärft. Zum einen kommen die Verbindungsabbrüche nun häufiger und das Senden des CPU Reset hat auch nicht mehr geholfen. Als Alternative könnte ich nun einen System Reset schicken der den gesamten Leser bootet. Habe ich aber nicht weiter implementiert.

    Ich tippe hier auf einen Memory Leak im Leser und habe den Bug der Firma FEIG gemeldet. Scheinbar hat noch ein weiterer Kunde diesen Fehler im System und konnte diesen mit dem Firmware Update auf Version 2.8.0 beheben. Der Leser an der Türe hat beim mir die Firmware Version 2.6.0.

    Ich erhielt also die aktuelle Firmware und das OBID Firmware Update Tool. In der Beschreibung fand ich allerdings den Hinweis dass die Konfiguration des Lesers beim Flashen zurückgesetzt werden kann. das wollte ich aber auf jeden Fall verhindern. Der Leser ist nämlich fest in der Außenwand verbaut und die Netzwerkkonfiguration mit der Firewall dazwischen ist recht aufwändig umzubauen. Daher bat ich um Klärung in welchen Fällen der Leser die Konfiguration beim Flashen verliert.

    Vor einer woche habe ich dann die Antwort vom technischen Support erhalten dass bei einem Update von 2.6.0 nach 2.8.0 die Konfiguration nicht zurückgesetzt wird. Daher habe ich mich heute an den Update gewagt.

    Zunächst mit dem Leser an meinem Schreibtisch (bisher Firmware Version 2.7.0).

    Das OBID Firmware Update Tool lies sich einfach installieren (Archiv entpacken) und starten. Nach eingabe von IP Adresse und Port findet ws auch sofort den Leser und fragt nach dem Passwort zur Authentisierung. Nachdem man dieses eingegeben hat, kann man die XML Datei mit der neuen Firmware wählen und das Flashen kann beginnen.

    Zunächst wird der Bootloader auf Version 1.0.0 gebracht (512 Blöcke) und danach autmatisch die Leser Firmware (2048 Blöcke). Beides ging reibungslos. Nach jedem Flash Vorgang wird der Leser automatisch gebootet (also insgesamt 2 mal).
    Am Ende kommt ein Beep und eine Ready Meldung.

    Der Start des Zugangskontrollsystems ging danach ohne weitere Modifikationen.

    TOP!

    Nun muss sich zeigen ob die Verbindungsabbrüche mit der neuen Firmware Version auch wirklich behoben sind. Ansonsten muss ich wohl wieder einen Call aufmachen.

    RFID TAG Initialisierung (3rd try) und Entwicklungsstand

    2015-09-23-Architektur-SchaubildEs ist vollbracht 🙂

    Vor ein paar Minuten hat mein Zugangs-Kontrollsystem eine vollständig Initialisierte Karte, mit Hilfe des rollenbasierten Zugriffsschutzes, validiert und mir den Zugang gewährt!

    Nach einigen Tagen Dokus im Internet suchen/lesen/verstehen, nach einigen Tagen reverse Engineering bin ich nun doch zu einem ersten Beta gekommen.

    Auf meiner ToDo Liste sind nun folgende Dinge:

    • Aufräumarbeiten im SourceCode um mehrfach genutzte Methoden in eine bzw. mehrere HelperKlasse(n) auszulagern.
    • Die Klasse ConfigFile erweitern um Methoden um gleich den passenden Datentyp zurück zu bekommen (String, Boolean, Integer, Byte).
    • Den Status des Türschlosses übermitteln auf den Server und entsprechend behandeln (Signal wenn Authorisiert, die Türe aber verriegelt ist).
    • Eine vernünftige Abbruchbedingung implementieren
    • Fixen des Bugs im „Card Management System“ zum Schlüsseltausch des PICC MasterKey (Default ist DES, ich will aber AES und die JavaSDK gibt das m.e. im Moment nicht her obwohl es via ChipMan funktioniert. Sollte also irgendwie gehen). Hier warte ich noch auf eine Lösung vom Technischen Support bei der Feig.
    • Das SDK und die zugehörigen Bibliotheken auf dem Raspberry installieren
    • Das Java Programm auf den Raspberry portieren und mit der PiFaceDigital 2 Klasse testen (und damit die Haustüre öffnen).
    • Ach ja und danach:
      • Firewall kaufen und einrichten
      • 2ten RFID Reader kaufen und einrichten (zur Karten Initialisierung)
      • RFID Tags kaufen, personalisieren und verteilen

    Initialisierung von Karten (2nd try)

    Im Moment bin ich an der Erstellung des „Card Management Systems“.
    Das Thema mit der DESFire Kommunikation hat mich nun wieder eingeholt. Daher habe ich wieder angefangen nach den DESfire spezifischen APDUs zu suchen.

    Um an die NXP Dokumentation „MIFARE DESFire – Implementation hints and examples,document number: 094532″ heranzukommen, habe ich nun auch einen Account im NXP Docstore beantragt. Mal sehen ob die sich melden, denn zu meinem eröffneten Ticket bei NXP.xom gab es in den letzten 3 Monaten keine Reaktion (selbst nach Rückfrage).

    Den logischen Ablauf stelle ich mir wie folgt vor:

    1. RFID tag formatieren
    2. PICC Applikation formatieren
    3. Keys ablegen
    4. Kommunikation mit RFID tag verschlüsseln
    5. PICC Applikation konfigurieren (z.B. Random UID)
    6. Applikation anlegen und Konfigurieren
    7. Kommunikation Applikation mit Keys sichern
    8. File anlegen
    9. Kommunikation File mit Keys sichern
    10. Initiale Daten in File schreiben

    Kaufsoftware oder selber machen

    Die Frage stellt sich mir auch wieder. Es gibt einiges an Kaufsoftware mit der man die Karten konfigurieren kann. [1][2] Allerdings sind diese relativ teuer. Der ChipMan kostet (mit DESFire Funktionalität) immerhin 798 Euro (Stand November 2014). Die Vollversion sogar 1598 Euro. Nichts desto trotz frage ich derzeit auch die Preise für BadgeMaker an.

    Parallel hierzu versuche ich natürlich mit der Feig SDK weiter zu kommen. Leider ist das SDK nicht wirklich gut Dokumentiert. Hauptinformationsquelle ist das Tutorial Dokument das allerdings nicht vollständig ist.
    Am Montag habe ich den tagHandler für MIFARE DESfire entdeckt, mal sehen ob ich hier weiter komme. Ich habe gemerkt das mit dem Protokoll wissen (APDUs) das Feig SDK etwas besser zu durchschauen ist. Daher auch der erneute Versuch an die MIFARE Doku zu kommen. Meine Internet-Recherche hat allerdings wieder ein paar interessante Quellen aufgetan (siehe [3] bis [6]).
    Wenn ich nicht weiterkomme muss ich wohl wieder mal den technischen Support der Feig bemühen mir zu helfen.

    Links:

    [1] MP-Sys – ChipMan: http://www.mpsys.de/
    [2] ScreenCheck BV – BadgeMaker (mit Encode add-on) http://en.badgemaker.info/
    [3] Ridrix’s Blog – APDU commands: https://ridrix.wordpress.com/tag/mifare-desfire/
    [4] NXP – MIFARE DESFire as Type 4 Tag: http://www.nxp.com/documents/application_note/AN11004.pdf
    [5] Jérémie Laval’s page – A Philips Datasheet: http://neteril.org/files/M075031_desfire.pdf
    [6] SmartCard Networking Forum – DESFIRE Specification: http://www.scnf.org.uk/smartstore/LASSeO%20docs/DESFIRE%20Specification%20V1%200.pdf

    Auf der Suche nach dem richtigen Reader

    Nachdem ich mich nun auf folgende Dinge festgelegt habe:

    • Verbindung von Server zum Reader via Ethernet
    • Raspberry PI 2 als Server

    Bin ich auf die Suche gegangen nach einem RFID Kartenleser den ich im Außenbereich anbringen kann.

    In dem Fachgebiet ist die Auswahl wirklich schwer. Zuletzt hatte ich Kontakt zur Firma SALTO Systems AG und der Firma FEIG ELECTRONIC GmbH.

    SALTO hatte sich auf meine erste Anfrage gar nicht gemeldet, die Firma Feig dagegen schon.

    Ich muss schon sagen, ich bin seit sicher 6 Wochen mit der Firma Feig in sehr regem Kontakt.

    Der Support der Firma Feig ist vorbildlich. Kaum vorstellbar das ich die dauernd mit irgendwelchen Fragen nerve, die antworten sogar mit sehr hilfreichen Informationen obwohl ich wirklich ein Miniprojekt am Laufen habe.

    Ich bin hoch zufrieden mit der FEIG ELECTRONIC GmbH und bin bestrebt alles zu tun um hier bleiben zu können.

    Nach einigen Fragemails und hin und her habe ich mich für den Feig OBID RFID Leser CPR50.10-E  entschieden. dieser unterstützt den Online Modus und die Ethernet Verbindung.

    Zudem gibt es die Möglichkeit diverse SDKs frei für die Software Entwicklung zu dem Leser dazu zu bekommen. Da ich von NXP noch immer keine Antwort habe, hoffe ich mit den SDKs um die RFID Kartenbefehle ein wenig herum zu kommen.

    Leider konnte mir die Firma Feig nicht zusichern das der Reader mit dem Raspberry PI 2 läuft, der PI (1) ist wohl getestet.
    Die Firma bietete mir an den Leser 6 Wochen für Tests kostenlos zur Verfügung zu stellen was ich gerne annahm. Der Leser war 2 Tage später im Haus (echt fix).

    Dazu bekam ich noch Zugang zum downloadbereich auf dem die SDKs liegen.

    Ich muss sagen, der Leser und die SDKs sind wirklich gut beschrieben und es gibt auch Tutorials zu jedem SDK. Angeboten wird Linux (C++), .NET und Java als SDK.

    Da ich mit den enryption Ciphers eh schon mit Java begonnen hatte, habe ich nun angefangen hier das Java SDK zu verwenden.
    Die Kommunikation mit dem Reader ist proprietär, man muss also (je nach OS) die entsprechenden Libraries installieren. Nach einigen Startschwierigkeiten habe ich es dann doch unter windows mit Eclipse zum Laufen gebracht.
    Nach ein paar Seiten Tutorial hatte ich die Verbindung zum Leser via Ethernet hergestellt.

    Zeit das ganze auf den Raspberry PI 2 zu transportieren um die generelle Funktion zu testen. die properitären Libraries lassen sich schnell installieren (.so files in /usr/lib kopieren und ein paar Symlinks anlegen).
    Die Größte Schwierigkeit ist eigentlich die passenden Libs für den Prozessor zu finden (armv7-a_vfpv3_hard).
    Das Java Programm hab ich via Eclypse in ein JAR gepackt und auf den Raspberry transportiert.

    Der Connection Test zum RFID Leser schlug leider bislang fehl. Java sagt mir dass es die libfeusb.so nicht finden kann.
    Um den Installationsprozess auf Linux zu prüfen hab ich die passenden Libs für Ubuntu herausgesucht und installiert. Hier hat der Verbindungstest auf anhieb funktioniert.
    Diverse Traces (strace) zeigten mir dass Java die libfeusb.so findet und öffnet. Wenn ich den strace mit ubuntu vergleiche, bekomme ich nach der Öffung der libusbfe.so ein Zugriff auf die libusb.so.

    Die Feig usb library basiert wohl auf die recht alte libusb 1.0.12.
    Diese habe ich von Sourceforge geladen und auf dem Raspberry compilliert und installiert. Leider ohne Erfolg. Ich werde mich die Tage wohl wieder mal an den Support wenden müssen, wobei ich hier langsam schwarz sehe da die den Raspberry PI 2 nicht offiziell unterstützen.

    Da der Support der FEIG ELECTRONIC GmbH aber so prima ist, werde ich mich wohl auf die Suche nach einer anderen Serverplatform machen müssen.
    Den RFID Leser habe ich jetzt noch 20 Tage für Tests zur Verfügung.

    Im Zweifel werde ich Ihn kaufen – das Ding ist nämlich richtig gut.

    MIFARE DESFire EV1 via pcsc-perl

    Der RFID Chip machte und macht mir noch immer einige Sorgen.

    Die Kommunikation erfolgt via sogenannter APDU Kommandos. Das sind 8 byte HEX Strings. [2]
    Es gibt wohl nach ISO Standard irgendwelche standard Befehle und es gibt zusätzlich einen DESFire EV1 proprietären Befehlssatz.

    Die ISO Befehle sind leider nur rudimentär beschrieben. [2] Jedenfalls habe ich nichts adequates gefunden. Schlimmer noch, die DESFire EV1 Befehle sind gar nicht öffentlich zu bekommen.

    Es soll eine Dokumentation von NXP geben die sich „MIFARE DESFire – Implementation hints and examples,document number: 094532″ nennt. In diversen Foren ist davon die Rede dass man die nur nach Unterzeichnung einer NDA bekommt.
    Um irgendwie weiter zu kommen habe ich nun einen Account bei NXP.com erstellt und am 1.6. eine Anfrage beim Support erstellt (diese ist Stand heute noch nicht beantwortet worden). Wir harren also der Dinge.

    Nichts desto trotz ist es mir nach einiger Recherche gelungen die Basisdaten auszulesen aus einer nicht Verschlüsselten blanko RFID Karte. Also welche Grundlegende Konfiguration diese hat, die UID und ein paar Infos zum Betriebssystem und der Hardware. Hier ein Beispiel (der Quellcode ist NICHT vollständig, es sind nur ein paar Ausschnitte des gesammten Programms):

    [..]
    # PC/SC Handling
    use Chipcard::PCSC;                # to connect to card reader
    use Chipcard::PCSC::Card;          # to read smart card
    [..]
    #---------------------------------------------------------------------#
    # sendAPDU
    # description: send APDU command and receive data
    # input: object (hCard), string (APDU comand)
    # return: string (APDU response)
    #---------------------------------------------------------------------#
    sub sendAPDU
      {
      my $card = shift;
      my $APDU_in = shift;
    
      my $SendData = Chipcard::PCSC::ascii_to_array($APDU_in);
      my $RecvData = $card->Transmit($SendData);
      if ($RecvData)
        {
        my $APDU_out = Chipcard::PCSC::array_to_ascii($RecvData);
        return ($APDU_out);
        }
      else
        {
        return(undef);
        }
      }
    #---------------------------------------------------------------------#
    # sendAPDUwithSW
    # description: send APDU command and receive data and status word
    # input: object (hCard), string (APDU comand)
    # return: string (APDU response), string (APDU status word)
    #---------------------------------------------------------------------#
    sub sendAPDUwithSW
      {
      my $card = shift;
      my $APDU_in = shift;
    
      my $SendData = Chipcard::PCSC::ascii_to_array($APDU_in);
      my $RecvData = $card->Transmit($SendData);
      my $sw_r = pop(@{$RecvData});
      my $sw_l = pop(@{$RecvData});
      my $sw = [$sw_l, $sw_r];
    
      my $APDU_out = Chipcard::PCSC::array_to_ascii($RecvData);
      my $SW = Chipcard::PCSC::array_to_ascii($sw);
    
      return ($APDU_out, $SW);
      }
    #---------------------------------------------------------------------#
    # getPICCData
    # description: get the Cards manufacturing data
    # input: object (hCard)
    # return: hash table reference
    #   hardware_vendor_id  => Vendor ID in hex
    #   hardware_type       => Hardware Type
    #   hardware_subtype    => Hardware Subtype
    #   hardware_version    => Hardware Version Number
    #   hardware_storage    => Storage size in bytes
    #   hardware_protocol   => Hardware protocol
    #   software_vendor_id  => Vendor ID in hex
    #   software_type       => Software Type
    #   software_subtype    => Software Subtype
    #   software_version    => Software Version Number
    #   software_storage    => Storage size in bytes
    #   software_protocol   => Storage protocol
    #   batch_number        => Batch Number
    #   calendar_week       => Calendar week of production
    #   production_year     => Year of production
    #---------------------------------------------------------------------#
    sub getPICCData
      {
      my $card = shift;
    
      my $response='';
      my $PICC = {};
    
      # get Hardware data
      $response = sendAPDU($card, '60');
      if (!$response) { return(undef); }
      # AF 04 01 01 01 00 1A 05
      $PICC->{'hardware_vendor_id'} = substr($response, 3, 2);
      $PICC->{'hardware_type'} = substr($response, 6, 2);
      $PICC->{'hardware_subtype'} = substr($response, 9, 2);
      my $HWVerMaj = substr($response, 12, 2);
      my $HWVerMin = substr($response, 15, 2);
      $PICC->{'hardware_version'} = hex($HWVerMaj).'.'.hex($HWVerMin);
      my $HWStorage = substr($response, 18, 2);
      #$PICC->{'hardware_storage'} = hex($HWStorage);
      $PICC->{'hardware_storage'} = $HWStorage;
      $PICC->{'hardware_protocol'} = substr($response, 21, 2);
    
      # get Software data
      $response = sendAPDU($card, 'AF');
      if (!$response) { return(undef); }
      $PICC->{'software_vendor_id'} = substr($response, 3, 2);
      $PICC->{'software_type'} = substr($response, 6, 2);
      $PICC->{'software_subtype'} = substr($response, 9, 2);
      my $SWVerMaj = substr($response, 12, 2);
      my $SWVerMin = substr($response, 15, 2);
      $PICC->{'software_version'} = hex($SWVerMaj).'.'.hex($SWVerMin);
      my $SWStorage = substr($response, 18, 2);
      #$PICC->{'software_storage'} = hex($SWStorage);
      $PICC->{'software_storage'} = $SWStorage;
      $PICC->{'software_protocol'} = substr($response, 21, 2);
    
      # get production data
      $response = sendAPDU($card, 'AF');
      if (!$response) { return(undef); }
      $PICC->{'batch_number'} = substr($response, 24, 14);
      my $ProdCW = substr($response, 39, 2);
      $PICC->{'calendar_week'} = $ProdCW;
      my $ProdYR = substr($response, 42, 2);
      $PICC->{'production_year'} = $ProdYR + 2000;
    
      return($PICC);
      }
    [..]
    
    my $hContext = new Chipcard::PCSC($Chipcard::PCSC::SCARD_SCOPE_SYSTEM, 0);
    my @ReadersList = $hContext->ListReaders ();
    my $ReadersName = $ReadersList[0];
    $readers_states[0]={ 'reader_name' => $ReadersName };
    # ignore first event
    my @StatusResult = $hContext->GetStatusChange(\@readers_states);
    foreach my $reader (@readers_states) { $reader->{'current_state'} = $reader->{'event_state'}; }
    
    [..]
    
    # Initialize  Card Object to read data from card
    my $hCard = new Chipcard::PCSC::Card($hContext,$ReadersName,$Chipcard::PCSC::SCARD_SHARE_EXCLUSIVE,$Chipcard::PCSC::SCARD_PROTOCOL_T0);
    
    # get UID from Card
    my ($CARD_UID, $sw) = sendAPDUwithSW($hCard, 'FF CA 00 00 00');
    print DATETIMESTRING().'   APDU state: '.Chipcard::PCSC::Card::ISO7816Error($sw).' ('.$sw.')'."\n";
    print DATETIMESTRING().'   Card UID: '.$CARD_UID."\n";
    [..]
    my $piccData = getPICCData($hCard);
    [..]
    my $piccApp = getPICCApp($hCard);
    [..]
    $hCard->Disconnect($Chipcard::PCSC::SCARD_EJECT_CARD);
    $hCard = undef;

    Der nächste Schritt ist, eine Authentisierung hinzubekommen. Zum Verfahren findet man einige Beiträge im Netz – allerdings nie so richtig vollständig. [3a][3b][3c][4][5a][5b][6]

    Die Desfire unterstützt als Verschlüsselungs Algorithmus DES, 3-DES und AES. Leider konnte ich keines der Beispiele im Netz mit Hilfe der Per Cipher Engins nachprogrammieren. Es scheint hier zu generellen Implementationsproblemen zu kommen. Egal was ich anwende CBC / noPadding via DES, 3-DES oder AES, nichts scheint die selben Ergebnisse zu reproduzieren wie in der Beispielen im Internet.

    Ja, ich konnte das Licht im Büro ein und Ausschalten (hat meinen 5 Jährigen schwer beeindruckt) aber es ist mir dann doch zu unsicher nur mit der UID einer Karte etwas freizuschalten. Daher habe ich das Thema mit Perl zu Seite gelegt und angefangen Java zu lernen.

    Ein paar Tage später konnte ich immerhin schon 3 der 5 auffindbaren Beispiele reproduzieren.

    Die Idee aus Perl heraus ein Java zu triggern hatte ich tatsächlich kurz gehabt aber dann doch wieder verworfen. Wie schon gesagt, ich habe auch null Info von NXP.com bis heute.

    Mahl ehrlich, das ist wie wen jemanden einen USB Stick verkauft der nicht vom Betriebsystem erkannt wird und man sagt dem Käufer auch nicht wie er ihn zum laufen bekommt, der der Treiber ist geheim. Meines Erachtens ziemlicher Schwachsinn.

    Links:

    [1] WikiPedia: Application Protocol Data Unit (APDU)
    [2] CardWerk: ISO 7816 Smart Card Standard
    [3a] http://stackoverflow.com/questions/14319321/how-can-i-do-native-authentication-in-desfire-ev1
    [3b] http://stackoverflow.com/questions/14117025/des-send-and-receive-modes-for-desfire-authentication
    [3c] https://n3vrax.wordpress.com/2011/07/23/des-algorithm-java-implementation/
    [4] https://ridrix.wordpress.com/2009/09/19/mifare-desfire-communication-example/#comment-87
    [5a] http://database.developer-works.com/article/15751843/Mifare+DESfire+card+Authentication!!!!!
    [5b] https://community.oracle.com/thread/1751843
    [6] http://stackoverflow.com/questions/21257442/mifare-desfire-ev1-authentication-using-aes

    RFID Chipauswahl und der erste RFID Reader

    Für das Zugangs Kontrollsystem via RFID braucht man nun auch die passende KArte.

    Leider gibt es eine Fülle unterschiedlicher RFID Chips und Frequenzen.

    Relativ schnell habe ich mich aber auf 13,56MHz eingeschossen.

    Die Chipauswahl war etwas schwieriger, nach aufstellung der wichtigsten Chips und deren features habe ich mich für den „MIFARE DESFire EV1“ entschieden.

    Der chip scheint, nach eineigen Recherchen, der Standard für solche Systeme zu sein. Zudem hat er jede menge Speicherplatz.

    Nun brauch ich nur noch ein Gerät das die Dinger beschreibt. Und ein paar Testchips.

    Ich habe mich für einen „ADRBv2 USB NFC/RFID Leser“ entschieden, da dieser von der libnfc unter Linux unterstützt wird. Wie sich später herausstellte war die Investition wohl umsonst.

    Leider habe ich den RFID Leser nicht unter meiner Ubuntu VM zum fliegen bekommen, auch habe ich einige Zeit damit verbracht das Ding mit einen Raspberry PI B+ um arbeiten zu bewegen. Leider ebenfalls ohne Erfolg. Die mitgelieferten Treiber liesen sich, auch nach diversen manuellen eingriffen, nicht compilieren.

    Nach freigabe durch meinen Finanzminister habe ich dann das „ChipMan Starter-KIT“ der Firma MB-Sys GmbH gekauft. Da war dann eine Software dabei, ein paar Testkarten und ein „SCM SCL011 USB Reader“.

    Der Lief dann unter Windows mit der Software.

    Erste Erfolge: Ich kann eine leere RFID Chipkarte einlesen.

    Ich habe gelernt, die Desfire EV1 Organisiert sich in „Applikationen“ und „Dateien“. Dann hörte es auf bei mir. Das Schreiben mit der Software hat nicht ganz so geklappt wie ich erhofft hatte und wenn, was sollte ich schreiben.

    Nun, aber was mir gelungen ist, ich habe den Reader via PC/SC Treiber auf dem Raspberry zum laufen gebracht.

    Mit dem Perl Modul pcsc-perl konnte ich sogar Anfangen die RFID Karten auszulesen.

    Aber damit gingen die Schwierigkeiten un richtig los.