ESPNOW Keyfob: Unterschied zwischen den Versionen

Aus Hackerspace Ffm
Wechseln zu: Navigation, Suche
(Protokoll)
(Kommandos)
 
(8 dazwischenliegende Versionen von einem anderen Benutzer werden nicht angezeigt)
Zeile 3: Zeile 3:
  
 
=== Hardware ===
 
=== Hardware ===
Einfachste Version: ESP01S oder ESP12S wird per CR2032 Knopfzelle über Taster mit Strom versorgt.
+
Einfachste Version: ESP01S oder ESP12S wird per CR2032 Knopfzelle über Taster mit Strom versorgt. Evtl. wird ein Pufferkondensator benötigt, weil recht hohe Stromspitzen auftreten können, die die Knopfzelle nicht schafft.
  
 
=== Details ===
 
=== Details ===
 
* Grundidee:
 
* Grundidee:
 
** Knopf wird gedrückt, ESP wird aktiviert  
 
** Knopf wird gedrückt, ESP wird aktiviert  
** Keyfob fordert Challenge von der Tür an (Random value min 32bit) - ESPNow Broadcast
+
** Private+Public Key und Name werden eingelesen, Test ob Public Key stimmt
 +
** Keyfob fordert Challenge 'c' mit signierter Nachricht von der Tür an (Challenge egal) - ESPNow Broadcast
 
** Wenn eine Tür in der Nähe ist, sendet sie eine Challenge zurück, die sie sich merkt
 
** Wenn eine Tür in der Nähe ist, sendet sie eine Challenge zurück, die sie sich merkt
 
** Challenge wird von Keyfob empfangen
 
** Challenge wird von Keyfob empfangen
** Keyfob baut Ed25519 signierte Nachricht und sendet sie per ESPNow Broadcast zur Tür zurück
+
** Keyfob baut Ed25519 signierte Nachricht 't' für trigger und sendet sie per ESPNow Broadcast zur Tür zurück
*** Nachrichtenlänge (muss mit ESPNow Paketlänge übereinstimmen)
+
*** Public Key (32 Bytes)
+
*** Name      (32 Bytes, 0 gefüllt)
+
*** Signatur  (64 Bytes)
+
*** Challenge  (32 Bytes)
+
*** Aktion    (1-xx Bytes) 'Open'+0
+
 
** Tür empfängt Nachricht. Wenn Signatur, Challenge, Länge und alles andere stimmt, wird Aktion ausgefürt.
 
** Tür empfängt Nachricht. Wenn Signatur, Challenge, Länge und alles andere stimmt, wird Aktion ausgefürt.
 
*** Public Key inkl. Name muss 1:1 in der Tür vorhanden sein - daran sind die User-Rechte gespeichert.
 
*** Public Key inkl. Name muss 1:1 in der Tür vorhanden sein - daran sind die User-Rechte gespeichert.
 
*** Wichtig: Aktuelle challenge muss nach der Ausführung auf ungültig gesetzt werden!
 
*** Wichtig: Aktuelle challenge muss nach der Ausführung auf ungültig gesetzt werden!
 
*** War der Aufbau richtig, aber der Nutzer (=Public Key) nicht bekannt, wird dieser zwischengespeichert
 
*** War der Aufbau richtig, aber der Nutzer (=Public Key) nicht bekannt, wird dieser zwischengespeichert
** Tür bestätigt ggf. Nachricht (nicht Pflicht)
+
** Tür bestätigt Nachricht  
 
** ESP geht in Power-Off Mode.
 
** ESP geht in Power-Off Mode.
  
Zeile 77: Zeile 72:
 
| 128 || 8 || Challenge Respone
 
| 128 || 8 || Challenge Respone
 
|-
 
|-
| 136 || 70 || Kommando (0-filled)
+
| 136 || 70 *1 || Kommando (0-filled)
 
|}
 
|}
 +
*1 Länge kann auch anders sein, definiert durch drüberliegendes Protokol, dass die Länge überträgt.
  
 
==== Kommandos ====
 
==== Kommandos ====
 
Hier die Kommandos. Die meisten Kommandos werden hinterlegte Rechte und gültige Signaturen + Challenges benötigen.
 
Hier die Kommandos. Die meisten Kommandos werden hinterlegte Rechte und gültige Signaturen + Challenges benötigen.
* 'c': Get Challenge. Hierbei wird die Challenge nicht überprüft (sollte aber mit Random gefüllt werden). Je nach Sicherheitskonzept gibt es nur bei hinterlegten Public Keys auch eine Challenge zurück.
+
* 'c': Get Challenge. Hierbei wird die Challenge nicht überprüft, auch damit die Übertragung schneller abläuft (Test der Challenge dauert etwa 100ms). Je nach Sicherheitskonzept gibt es nur bei hinterlegten Public Keys auch eine Challenge zurück.
* 't': Trigger. Triggert das Lock. Was hierbei passiert ist vom Schloss abhängig. Das ist das Kommando für KeyFobs mit nur einem Button. Einige Schlösser lassen sich damit nur öffnen, andere Öffnen und Schliessen.  
+
* 't': Trigger. Triggert das Lock. Was hierbei passiert ist vom Schloss abhängig. Das ist das Kommando für KeyFobs mit nur einem Button. Einige Schlösser lassen sich damit nur öffnen, andere Öffnen und Schliessen.
 +
* 'U': Unlock debug und Webserver mode. Gerät wird sehr offen, nur kurz benutzen, danach Reset machen. Benötigt spezielle Rechte.
 +
* 'O': Tür öffnen.
 +
* 'C': Tür schließen.
 +
* 'R': Rest. Beendet auch den debug modus.
  
 
==== Antworten ====
 
==== Antworten ====
Signaturen sind normalerweise nicht nötig. Um ggf. einen bestimmten Anfrager zu unterscheiden wird dessen Public Key zurück gesendet. Bei Broadcasts ist dieser mit 0 gefüllt. Auch werden 4 Bytes für den Antworttyp definiert:
+
Signaturen sind normalerweise nicht nötig. Um ggf. einen bestimmten Anfrager zu unterscheiden wird dessen Public Key zurück gesendet. Bei Broadcasts ist dieser mit 0 gefüllt. Hier wird auch immer eine neue Challenge übertragen, die eine Zeit lang gültig ist.
 
{| class="wikitable"  
 
{| class="wikitable"  
 
|+ Hackffm Lock Protocol - Antwort
 
|+ Hackffm Lock Protocol - Antwort
 
|-
 
|-
 
! Offset !! Länge in Bytes !! Inhalt
 
! Offset !! Länge in Bytes !! Inhalt
 +
|-
 +
| -4 || 4 || Präambel "D00a"
 
|-
 
|-
 
| 0 || 32 || Last public key of device that sent command (000.. for unspecific)
 
| 0 || 32 || Last public key of device that sent command (000.. for unspecific)
 
|-
 
|-
| 32 || 4 || 'ANSW' for command answers, 'INFO' for generic infos, 'ERRR' for errors
+
| 32 || 8 || Next challenge
 
|-
 
|-
| 36 || x || Command specific answer
+
| 40 || x || Command specific answer
 
|}
 
|}
  
Kommando Antworten, eingeleitet mit 'ANSW':
+
Kommando Antworten:
* 'c' + 32 byte: Nächste zu verwendende Challenge (verfallen nach einigen Sekunden, evtl. können mehrere gültig sein)
+
* 'c': Nächste zu verwendende Challenge (verfallen nach einigen Sekunden, evtl. können mehrere gültig sein)
* 'tok' : Trigger ausgeführt.
+
* 't': Trigger ausgeführt.
 
+
* 'E': Error, more info in following bytes.
Bei 'INFO' und 'ERRR' werden typischerweise Klartext Antworten gesendet.
+

Aktuelle Version vom 20. Dezember 2024, 23:10 Uhr

Ziel

Wie ein Funkautoschlüssel können mit einem sehr kleinen Gerät die Türen im Space sicher geöffnet werden. Benutzt wird dazu ein möglichst kleines ESP8266 oder ESP32 Board und das ESPNow Protokoll.

Hardware

Einfachste Version: ESP01S oder ESP12S wird per CR2032 Knopfzelle über Taster mit Strom versorgt. Evtl. wird ein Pufferkondensator benötigt, weil recht hohe Stromspitzen auftreten können, die die Knopfzelle nicht schafft.

Details

  • Grundidee:
    • Knopf wird gedrückt, ESP wird aktiviert
    • Private+Public Key und Name werden eingelesen, Test ob Public Key stimmt
    • Keyfob fordert Challenge 'c' mit signierter Nachricht von der Tür an (Challenge egal) - ESPNow Broadcast
    • Wenn eine Tür in der Nähe ist, sendet sie eine Challenge zurück, die sie sich merkt
    • Challenge wird von Keyfob empfangen
    • Keyfob baut Ed25519 signierte Nachricht 't' für trigger und sendet sie per ESPNow Broadcast zur Tür zurück
    • Tür empfängt Nachricht. Wenn Signatur, Challenge, Länge und alles andere stimmt, wird Aktion ausgefürt.
      • Public Key inkl. Name muss 1:1 in der Tür vorhanden sein - daran sind die User-Rechte gespeichert.
      • Wichtig: Aktuelle challenge muss nach der Ausführung auf ungültig gesetzt werden!
      • War der Aufbau richtig, aber der Nutzer (=Public Key) nicht bekannt, wird dieser zwischengespeichert
    • Tür bestätigt Nachricht
    • ESP geht in Power-Off Mode.
  • Fobs an die Tür anlernen:
    • Neuer Keyfob versucht Tür zu öffnen.
    • Tür öffnet nicht, merkt sich aber den letzten ungültigen Nutzer (Public Key + Name)
    • Keyfob mit höheren Rechten sendet Aktion 'Review'+0
    • Tür speichert letzten ungültigen Nutzer in Review Speicher und zeigt diesen im Display an
    • Keyfob mit höheren Rechten sendet Aktion 'AddReviewed'+0
      • Tür nimmt Nutzer nun auf mit Standard-Rechten
    • Keyfob mit höheren Rechten sendet Aktion 'CancelReviewed'+0
      • Tür verwirft letzten ungültigen Nutzer, zeigt auch nichts mehr in Review Speicher an
      • Passiert auch automatisch nach 30s

Software / Protokol

Konzept

Trennung in Ebenen

  • Übertragungsebene: Wrapper bauen für TCP, UDP, HTTP, WebSocket oder ESPNow
  • Authentifizierungsebene: Checkt Signatur, checkt Callenge/Response, ermittelt Nutzerrechte, hält Nutzerdatenbank
  • Kommandoebene: Parst Kommandos


Nutzer

  • Können mehrere Schlüssel (Keys) haben (erstmal immer Ed25519 Private-Keys)
  • Zusätzlich zum Key sollte ein Klartextname (32-Byte String) zur Zuordnung hinterlegt werden
  • Jedes Schloss speichert Public-Key + Klartextname + Rechte pro Nutzer


Schlüsselfile

Statt mit einem KeyFob kann die Tür auch per anderer Hardware geöffnet werden, z.B. über ein Webinterface. Dazu muss der Nutzer seinen Private-Key irgendwo abspeichern. Das Format dazu ist ein ASCII-Hex-String, je 2 Zeichen pro Byte 00..FF, mit folgendem Aufbau:

  • 32 Byte (64 Zeichen) Private Key
  • 32 Byte (64 Zeichen) Public Key (zur Kontrolle)
  • 32 Byte (64 Zeichen) Klartextname (0 gefüllt)

Der Parser für diese Datei sollte alle Zeichen die nicht für HEX sind sowie alle Zeichen nach dem 3x 32x Byte ignorieren.

Wichtig: Der Private Key darf nie übertragen werden, sonst ist das Konzept für die Füße. Er darf nur z.B. lokal im Browserscript geladen und verwendet werden um eine Nachricht zu signieren.

Protokoll

Hier das gemeinsamme Protokoll, das unabhängig von der Übertragungsebene sein sollte. Damit es auch einfach per ESP-Now übertragen werden kann, sollte es kürzer als 250 Byte sein.

Hackffm Lock Protocol - Anfrage
Offset Länge in Bytes Inhalt
-4 4 Präambel "D00r"
0 64 ED25519 Signatur über alle folgenden Bytes
64 32 ED25519 Public Key
96 32 Name (Klartext, UTF-8, 0-filled
128 8 Challenge Respone
136 70 *1 Kommando (0-filled)
*1 Länge kann auch anders sein, definiert durch drüberliegendes Protokol, dass die Länge überträgt.

Kommandos

Hier die Kommandos. Die meisten Kommandos werden hinterlegte Rechte und gültige Signaturen + Challenges benötigen.

  • 'c': Get Challenge. Hierbei wird die Challenge nicht überprüft, auch damit die Übertragung schneller abläuft (Test der Challenge dauert etwa 100ms). Je nach Sicherheitskonzept gibt es nur bei hinterlegten Public Keys auch eine Challenge zurück.
  • 't': Trigger. Triggert das Lock. Was hierbei passiert ist vom Schloss abhängig. Das ist das Kommando für KeyFobs mit nur einem Button. Einige Schlösser lassen sich damit nur öffnen, andere Öffnen und Schliessen.
  • 'U': Unlock debug und Webserver mode. Gerät wird sehr offen, nur kurz benutzen, danach Reset machen. Benötigt spezielle Rechte.
  • 'O': Tür öffnen.
  • 'C': Tür schließen.
  • 'R': Rest. Beendet auch den debug modus.

Antworten

Signaturen sind normalerweise nicht nötig. Um ggf. einen bestimmten Anfrager zu unterscheiden wird dessen Public Key zurück gesendet. Bei Broadcasts ist dieser mit 0 gefüllt. Hier wird auch immer eine neue Challenge übertragen, die eine Zeit lang gültig ist.

Hackffm Lock Protocol - Antwort
Offset Länge in Bytes Inhalt
-4 4 Präambel "D00a"
0 32 Last public key of device that sent command (000.. for unspecific)
32 8 Next challenge
40 x Command specific answer

Kommando Antworten:

  • 'c': Nächste zu verwendende Challenge (verfallen nach einigen Sekunden, evtl. können mehrere gültig sein)
  • 't': Trigger ausgeführt.
  • 'E': Error, more info in following bytes.