Hi!
Ich habe ein kleines Problem. Ich habe ein System aus mehreren
Empfängern und einem Sender. Der Sender soll an die Empfänger Befehle
übertragen können. Soweit funktioniert das auch schon alles ganz gut.
Jetzt kommt das Problem: Die Empfänger müssen (annähernd) zweifelsfrei
nachprüfen können das ein Funkbefehl auch wirklich vom "echten" Sender
stammt. Auch eine Man-In-The-Middle oder Replay-Attacke muss
ausgeschlossen sein.
Bisher habe ich das ganze so realisiert:
Jeder Empfänger hat im EEPROM abgelegt ein Secret, dieses ist auch im
Sender bekannt. Außerdem gibt es sowohl in jedem Empfänger als auch im
Sender einen 6-Byte-Zähler (Sequenznummer).
Ein Funkbefehl wird nun gebildet aus: <Nutzdaten><Sequenznummer><Hash>.
Drumrum kommen natürlich noch Sachen wie CRC, Sync-Byte und
Befehlslänge, die aber für das eigentliche Problem nicht von Bedeutung
sind.
Der Empfang läuft dann folgendermaßen ab: Der Empfänger prüft ob die
mitgeschickte Sequenznummer größer ist als die gespeicherte
Sequenznummer. Wenn nicht -> Abbruch, kein gültiger Befehl.
Wenn die empfangene Nummer größer ist als die gespeicherte, wird aus den
Nutzdaten, dem Secret und der Sequenznummer ein Hash berechnet. Dieser
ist - da sich die Sequenznummer ja immer erhöht - niemals identisch,
eine Replay-Attacke scheidet insofern schonmal aus.
Die interne Sequenznummer des Empfängers wird bei Übereinstimmung des
gesendeten und gespeicherten Hashs als "neue letzte Sequenznummer" im
Empfänger gespeichert und ist damit "verbraucht".
Das Problem ist nun aber folgendes: Die Empfänger sind austauschbar,
auch der Sender kann wechseln. Die Empfänger müssen sich also bei jeder
neuen Zusammenstellung mit dem Sender "synchronisieren" damit sicher
gestellt ist, dass jeder Empfänger die Befehle auch umsetzt.
Am einfachsten wäre es natürlich beim Einschalten des Senders jeden
Empfänger einmal abzufragen an welcher Stelle er steht. Damit jedoch an
dieser Stelle keine Manipulation der Antwort möglich ist (Antwort: "ich
bin bei (2 ^ 48) - 2" - was bedeuten würde das nach 2 Befehlen ein
Überlauf auf 0 stattfindet der das System lahmlegt) müssten die
Empfänger wenn sie dem Sender antworten die Rückmeldung mit der eigenen
Sequenznummer verschlüsseln - und hier beißt sich die Katze in den
Schwanz..
Woher weiß der Empfänger hier das er nicht einer Replay-Attacke aufsitzt
und die zurückgemeldete Sequenznummer überhaupt nicht stimmt?
Wenn er eine falsche Meldung annimmt, könnte das im schlimmsten Fall
dazu führen, dass er bei einer "falschen" Sequenznummer startet -
nämlich bei einer, die eventuell vorher schonmal aufgezeichnet wurde..
Ein einfacher Weg wäre natürlich, vor dem Aufbau der Empfänger jeden
einmal per Kabel mit dem Sender zu verbinden um die Nummern
auszutauschen aber diese Lösung ist relativ umständlich. Schöner wäre es
natürlich, das über Funk hinzukriegen. Am besten natürlich auch noch
ohne das die Empfänger ihren eigenen Hash berechnen müssen - denn das
kostet auch Zeit und wird später nur beim Broadcast (Befehl an alle)
eingesetzt wo es keine Rolle spielt ob 5 oder 100 Empfänger da sind.
Ich hoffe es versteht jemand das Problem dahinter und weiß eine Lösung,
die sich relativ "schnell" (von der Ausführungsgeschwindigkeit)
implementieren lässt..
Liebe Grüße,
- Tobi
P.S: Wie gesagt, das System ist relativ sicherheitskritisch, also keine
TV-Fernbedienung oder sowas..
Soviel ich jetzt beim schnellen Durchlesen verstanden habe, möchtest du
schon die Funkschlüssel verschlüsselt über Funk austauschen.
Wenn ich mich nicht irre, wird das bei Bluetooth genau so gemacht,
vielleicht solltest du dich in die Richtung mal näher erkundigen wie das
gelöst ist.
Grüsse,
Killler07
Es ist doch immer wieder gut, Probleme aufzuschreiben.
Eventuell habe ich schon selbst eine Lösung gefunden. Mich interessiert
aber trotzdem eure Meinung dazu, und eventuell hilft es ja (wenns
klappt) auch jemand anderem.
Folgendes Verfahren:
Sender schickt an Empfänger x eine genügend breite (bitbreite)
Zufallszahl.
Dieser nimmt seine interne Sequenznummer, seine eindeutige Seriennummer
und die Zufallszahl + das interne Secret und berechnet daraus einen
Hash.
Dieser Hash wird zusammen mit der Sequenznummer und der Absenderadresse
an den Master geschickt.
Der nimmt dann wiederum die o.A. Daten und berechnet daraus einen Hash
und vergleicht beides. Bei Übereinstimmung ist die Sequenznummer gültig
und wird benutzt um die nächste Nummer zu finden mit der der Master dann
selbst seine Befehle senden kann.
Vorraussetzung für all dies ist natürlich, das die Zufallszahl wirklich
zufällig ist und nicht sequentiell ansteigt (dann könnte ja ein früher
bereits aufgezeichneter Befehl an entsprechender Stelle wieder
abgespielt werden). Die Zahl wird zwar aus einer fortlaufenden Nummer
generiert, jedoch ist der Zufallswert selbst ein Hash - aus einer Nummer
die der Master intern verwaltet und der Seriennummer des Masters.
Mögliche Angriffsszenarien:
>> Anfrage an den Empfänger wird manipuliert in:
- Zufallszahl: Empfänger sendet eine falsch signierte Nachricht zurück
-> Ungültig
- Ziel: Falscher Empfänger sendet Antwort zurück - falscher Hash ->
Ungültig
>> Antwort vom Empfänger wird manipuliert:
- Antwort von einem anderen Empfänger wird eingesetzt: Falsche Quelle,
falscher Hash -> Ungültig
- Antwort wird direkt manipuliert -> Falscher Hash
Weitere aufgekommene Frage:
- Kann ich das Secret, welches der Sender zur "Anfrage" benutzt für alle
Module benutzen oder gibt es dann Probleme (also nur beim Start des
Senders einmal diesen Zufallswert bestimmen)?
Ich glaube das könnte mit der Methode funktionieren, auch wenn sie etwas
langwieriger ist ;)
- Tobi
Hi schon wieder..
Danke für eure schnellen Anregungen. Die meisten Public-Key-System
scheiden leider aus, da ich nicht mehr viel Platz im atmega16 habe, um
noch viele Algorithmen zu implementieren.
Außerdem hätte ich dann vermutlich das Problem der Rechenzeit bei 14,1
MHz, das den Rahmen sprengen würde. Zumindest der Empfang der
Steuerbefehle sollte sich im Bereich von < 20ms abspielen (außer es
kennt jemand von euch eine Implementation die dies ermöglicht).
Im Moment benutze ich SHA1 zum Hashen und da liege ich bei ca. 10ms für
den hauptsächlich zeitkritischen Befehl (ja, ich weiß - angeblich ist es
gelungen die Sicherheit herabzusetzen - aber sooo technisch versierte
oder finanzstarkte Leute werden es darauf dann doch nicht abgesehen
haben).
Und nein, das System kennt die Uhrzeit nicht und muss auch relativ klein
und preisgünstig bleiben - d.H. möglichst ohne externe Hardware oder
Batterien zur Uhrzeitpufferung und aktualisierung auskommen..
Und nochmal nein, ich brauche im Prinzip keine Verschlüsselung. Ein
reines Aufzeichnen der Befehle ist nicht wirklich tragisch. Tragisch
wäre es nur, wenn diese aufgezeichneten Befehle danach nochmals gültig
sein könnten, was ich ja durch die Sequenznummer verhindere.
Wobei mir gerade auffällt das es kritisch sein könnte, einen Aufbau mit
"frischen" Empfängern zu machen, die bei einer anderen Anwendung noch
nicht dabei waren und deren Sequenznummern folglich noch irgendwo ganz
unten sind. Da wäre es dann doch möglich, mit einer Replay-Attacke das
ganze zu sprengen.
Eventuell sollte der Sender bei jedem Aufbau die Uhrzeit abfragen und
dann entsprechend die Sender initialiseren. Auch das müsste dann
allerdings auf sicherem Wege geschehen..
Vielleicht doch ein Public-Key-System auch wenns viel mehr Aufwand
ist..? :(
Vielen Dank für eure Hilfe!
- Tobi
Okay, mega16 mag zu klein sein. Ich bin mit der halben Implementation
(siehe oben) jetzt fast an der Grenze des Machbaren. Deshalb wird das
ganze auch auf den atmega32 hoch gehen. Ich erwarte trotzdem, das das
oben beschriebene Konzept funktioniert (und das vermutlich selbst auf
dem 16er).
Für RSA ist das ganze vermutlich auch mit dem atmega32 zu klein, aber
ich will ja auch möglichst ohne auskommen, vor allem weil (so liest man)
die Rechenzeit meist um den Faktor 500-1000 ansteigt was für die
Anwendung einfach nicht drin ist. Daran ändert auch kein größerer Atmel
was, die sind ja soweit ich weiß alle nur bis max. um die 20 MHz
spezifiziert.
Das einzige Problem wäre dann jetzt noch die Möglichkeit, das 10
Empfänger zu Hause stehen und nicht mitbekommen haben, das die
Sequenznummer nach oben gegangen ist und sich dann beim nächsten Einsatz
mit einem aufgezeichneten, niedrigeren Befehl ansprechen lassen ;)
Eventuell könnte ich dafür doch einen RTC-Chip benutzen, habe nach
Rücksprache mit meinem Hardware-Guru erfahren das die Stromaufnahme da
teilweise im Bereich der µA liegt. Muss man nurnoch gucken wie man den
Startwert über den RTC ermittelt. Sollte ja auch nicht so sein das der
Startwert sich genau Mitternacht ändert und dann das ganze System
auseinander bricht ;)
Die ATXMega haben ne Crypto Einheit. Da ist dann die Geschwindigkeit
nicht mehr so das Problem, wenn man die eingebauten Verschlüsselungen
verwendet (verwenden kann).
Hi,
nur mal so ein Gedanke. Wie behandelst du den Überlauf der
Sequenznummer?
Bei 2^48 Befehlen dauert das zware eine Weile, aber es wird passieren!
Einerseits schreibst du, das dann das System lahm gelegt wird. Das
sicherheitskritisches System fällt aus! Das sollte wohl eher kein
gewollter Anwendungsfall sein, oder?
Andererseits sollen sich bei "Systemstart" oder Systemänderung der
(neue) Sender auf die zuletzt verbrauchte Sequnznummer
"synchronisieren". Das aber erhöht die Wahrscheinlichkeit für das
Auftretens des Überlaufs!
Oder ich habe dich falsch verstanden.
Gruß
Andreas
Nein, du hast mich richtig verstanden. Das System impliziert, dass nach
x Anwendungen alle Systemkomponenten mit einem neuen Passwort wieder auf
0 gesetzt werden. Da der Master diesen Zustand erkennen kann, wird er
dies dem Anwender melden und der muss dann eben selbst "Hand anlegen"
indem er jedem Empfänger und dem/den Sendern das neue Passwort und die
neue Sequenznummer eben "einpflanzt".
Dafür wäre natürlich auch eine Methode per Funk denkbar, die (signiert
as usual) das neue Secret (geXORd mit z.B. SHA1(Passwort +
SequenzDieNieVorkommt) festlegt.
Da sehe ich nicht so das Problem, zumal man die Sequenznummer natürlich
auch so astronomisch hoch ansetzen kann das es bei den anvisierten 38400
Baud und konstantem Befehl-Senden 500 Jahre dauern würde bis der
Sequenzraum erschöpft ist..
Lieber wäre mir natürlich, aus einer verlässlichen Quelle ein
Systemdatum zu bekommen welches benutzt wird um die Sequenznummer von
vornherein festzulegen. Dann müsste man aber wiederum definieren, welche
Abweichung als OK angesehen wird und zusätzlich dafür sorgen, dass alle
Systemkomponenten wirklich auf der gleichen Zeitbasis laufen. Wieder
zusätzlicher Aufwand..
Ich habe das ganze gerade mal "real" durchgerechnet. Wenn ich mit 38400
Baud (= 4800 Byte/Sec) sende und meine Sequenznummer 6 Byte breit wäre
würde ich pro Sekunde 800 Sequenzen schaffen (6 Byte die der Befehl
mindestens breit sein müsste um die aktuelle Sequenznummer zu enthalten
= 6 Byte / 4800 Byte/Sek * 1 Sekunde => 800).
Den Fall das mehrere Systeme parallel im Einsatz sind brauche ich nicht
zu berücksichtigen, da dann ein weiteres System auch nicht mehr
Sequenzen pro Sekunde schafft und das ganze sich hinterher nicht addiert
(für beide Sequenzen die Empfänger in der gegebenen Zeit das gleiche
Maximum erreichen).
Bis zur Erschöpfung meiner Sequenzbreite muss ich 2 ^ 48 =
281474976710656 Sequenzen "abklappern". Pro Sekunde schaffe ich 800
davon.
2 ^ 48 / 60 (Sekunden) / 60 (Minuten) / 24 (Stunden) / 365 (Tage) ==>
11438 Jahre bis ich den Sequenzraum durchgenudelt habe (wohlgemerkt bei
ununterbrochenem Senden).
Das SOLLTE eigentlich genug sein, oder?
Kleines Update:
Das ganze wird jetzt folgendermaßen laufen (falls es jemand interessiert
;-)):
Das Grundkonzept (oben beschrieben) bleibt bestehen. Dazu kommt dann ein
RTC-Chip der die aktuellen Datum-/Uhrzeitwerte in eine entsprechende
Sequenznummer umwandelt.
Jeder Empfänger prüft beim Einschalten, ob die RTC noch eine
verlässliche Zeit meldet (Zeit größer als 0+/-60 Sekunden, ..). Wenn die
Zeit verlässlich ist, wird die Zeit - 300 Sekunden als Sequenznummer
übernommen. Dies geschieht jedoch nur solange die im EEPROM gespeicherte
Sequenznummer KLEINER ist.
Der Sender führt die gleiche Prozedur durch, subtrahiert jedoch nicht
300 Sekunden von der aktuellen Zeit - damit ist eine 5-Minütige
Karenzzeit sichergestellt, falls die Uhren der Empfänger zu sehr
vorgehen.
Er prüft jeden Empfänger auf den Status (RTC ok/nicht ok) und leitet
wenn die Uhrzeit nicht (mehr) verfügbar ist die folgende Sequenz ein:
Wenn der RTC keine Daten liefert oder die Platine noch nicht
entsprechend bestückt ist (die aktuellen Prototypen z.B.) wird aus der
eindeutigen, einmaligen Kennung des Empfängers, seiner im EEPROM
gespeicherten aber veralteten Sequenznummer und dem Secret ein SHA1-Hash
berechnet und an den Sender geschickt (= "Zufallswert"). Dieser fügt die
aktuell gültige Sequenznummer und nochmals das Secret hinzu und
berechnet darüber ebenfalls einen SHA1-Hash. Er schickt die aktuelle
Sequenznummer zusammen mit dem berechneten Hash an den Empfänger.
Dieser berechnet ob der SHA1-Hash stimmt, bei Gültigkeit übernimmt er
die Sequenznummer als aktuell.
Die zuletzt beschriebene Prozedur funktioniert immer zuverlässig, die
erste Methode ist jedoch schneller, da sie keine zusätzliche
Kommunikation und/oder Hash-Berechnungen erfordert und trotzdem sicher
verhindert, dass bereits benutzte Befehle (nach Ablauf der 5min
Karenzzeit) wieder verwendet werden.
Eine Wiederverwendung nach diesen 5 Minuten würde jedoch implizieren,
dass ein Empfänger innerhalb dieser 5 Minuten keinen anderen Funkbefehl
bekommen hat - somit müsste der Empfang komplett blockiert werden um die
Ausführung eines Befehls um 5min zu verzögern. Das ist für den gedachten
Einsatzbereich akzeptabel.
Damit ein später zugeschalteter Empfänger die aktuelle Sequenznummer
nachvollziehen kann (diese entspricht nach längerem Sendebetrieb einer
viel zu alten "Uhrzeit"), muss der Sender seine Sequenznummer regelmäßig
mit der aktuellen Uhrzeit die sein RTC liefert abgleichen.
Auch ist es sinnvoll, die Uhrzeit des Senders regelmäßig signiert an die
Empfänger weiterleiten und diese damit neu synchronisieren.
Die Abweichung zwischen dem Sender und einem beliebigen Empfänger darf
(wenn der Sender seine Sequenznummer z.B. jede Minute aktualisiert) bei
dem oben gewählten Wert von 300 Sekunden max. 4 Minuten betragen -
danach ist keine Kommunikation mehr möglich (bzw die Sequenznummer muss
mit der zweiten Methode erst wieder neu ausgehandelt werden, um die Uhr
im Empfänger richtig stellen zu können).
Außerdem ist natürlich eine regelmäßige Kontrolle der internen
RTC-Pufferung notwendig, um zu verhindern das der Chip irgendwann
ausfällt und die "lange" Prozedur notwendig wird.
Falls ihr noch Anmerkungen zum dem Verfahren oder andere Fragen habt,
immer her damit!
Danke für die viele Hilfe,
Tobi
Hm, hab da mal ne Frage:
Reicht es nicht wenn Du Dein „Datenpaket“( Sequenznummer, CRC usw.) mit
einem Masterkey verschlüsselst.
Es gibt doch schnelle Verschlüsselungsalgos die nicht rückrechenbar sind
und unter anderem mit Permutationstabellen arbeiten.
Jedem Teilnehmer muss lediglich der der Algo und der Masterkey bekannt
sein.
Neue Teinehmer startest Du mit der Sequenznummer Null.
Der EEprom vom ATmega32 macht 100.000 Schreibzyklen. Reicht das?
Mit freundlichem Gruss
AKtronik
Hi!
Hm ja, theoretisch würde das auch reichen, ja. Das Problem mit der
Aktualität der Sequenznummern bliebe weiterhin. Insofern wäre es dann
natürlich egal, ob ich "nur" SHA1 zum Hashen einsetze oder die Pakete
komplett verschlüssele.
Das einzige Problem ist dann die Geschwindigkeit: Wenn ich den
"normalen" atmega16 oder 32 mit 14,7456 MHz einsetze, liegt der jetzt
benutzte SHA1 weit unter 1ms pro Byte. Wenn ich die
Geschwindigkeitsvergleiche auf
http://www.das-labor.org/wiki/Crypto-avr-lib
ansehe, macht mir das für andere Methoden wenig Mut. Als einziger
vergleichbar schneller (sogar schnellerer) Algo über den ich bisher
nichts Negatives finden konnte bleibt XTEA übrig, allerdings finde ich
darüber dann wieder so wenig, dass ich nicht sicher bin ob er wirklich
sicher ist ;-)
Die max. 100.000 garantierten Schreibzyklen fange ich ab, indem ich die
Sequenznummer nur in der Abschaltsequenz ins EEPROM schreibe, die durch
einen Interrupt beim Abschalten der Versorgungsspannung ausgelöst wird.
In der Zeit die der µC dann noch zum Schreiben der Daten benötigt, wird
er über einen Kondensator versorgt so das er das Schreiben dieser 6
Bytes "überlebt".
Gruß,
Tobi
Hallo Tobias,
ich habe mir nicht alles ganz genau durchgelesen, aber hier mal eine
andere Variante, die sich relativ einfach auf den Empfängern umsetzen
lässt, aber etwas mehr Aufwand beim Sender erfordert.
Zur Authentifizierung des Senders kannst Du auch eine sog. Hash-Kette
verwenden. Dabei wird der Sender mit einer Zufallszahl initialisiert und
berechnet im Anschluss n Hash-Werte, wobei der i. Hash-Wert durch
Anwenden der Hash-Funktion auf den i-1. Wert ermittelt wird. Der letzte
Wert der Hash-Kette wird den Empfängern einmalig mitgeteilt.
Verschickt der Sender jetzt einen Befehl an die Empfänger, verwendet er
als zur Authentifizierung den n-1. Hash-Wert der Hash-Kette. Dein
Funkbefehl hat dann beispielsweise die Form <i-1. Hash-Wert der
Hash-Kette, Nutzdaten, CRC, Hash-Wert über das Ganze>.
Jeder Empfänger kann nun anhand des i-1. Hash-Wertes aus der Hash-Kette
überprüfen, ob dies ein gültiger Befehl ist, denn der Hash-Wert des i-1.
Elementes der Hash-Kette ist ja der das i. Element, welches bereits auf
dem Empfänger vorhanden ist. War der Befehl gültig, ersetzt der
Empfänger den i. mit i-1. Wert der Hash-Kette. Ein Angreifer kann somit
den Befehl nicht wiederholen, da er nicht als gültig erkannt wird.
Da nach n Befehlen die Hash-Kette verbraucht ist, wird vorher ein sog.
Rekeying benötigt. Dazu braucht man ein zusätzlicher Befehl, der die
Hash-Kette wechselt und den letzten gültigen Wert ersetzt.
Das Verfahren loest leider nicht alle Probleme, so muss sichergestellt
sein, dass beim Rekeying alle Empfaenger online sind, sonst akzeptieren
die Empfaenger, die das Rekeying verpasst haben, keine Befehle mehr.
Gruss
Micha
Hi Michael!
Ja, eine Hash-Kette wäre auch eine Möglichkeit gewesen. Leider erweist
sich die von dir angesprochene Schwäche als das größte Problem einer
solchen Implementation.
Da nicht alle Empfänger bei jedem Aufbau (der meist nur einige wenige
Stunden besteht) eingesetzt werden, und es durchaus vorkommen kann das
bei einem einzigen Einsatz 1000-2000 Befehle abgesetzt werden, macht
eine Hash-Kette keinen Sinn. Das erste (lösbare) Problem ist, dass die
Hash-Werte im Sender gespeichert werden müssen. Wenn ich jedoch für 2000
Befehle die Hash-Werte vorhalten muss, brauche ich bei (z.B.) 128-Bit
Hashlänge allein schon 32k Speicher NUR dafür.
Das größte Manko ist dann allerdings die Möglichkeit, das ein Empfänger
da steht, der schon 4 mal nicht im Einsatz war. Der müsste - selbst wenn
die Hash-Kette lang genug wäre - erst alle schon benutzten 2000 Hashes
durchrechnen um zu merken, dass ein gültiger Wert benutzt wurde.
Da ich dafür bei 128 Bit Hash-Werten (16 Byte * 0,5ms) => 8ms pro Wert
brauchen würde, wäre der Empfänger 16 Sekunden damit beschäftigt, die
Hash-Kette durchzugehen (das gleiche natürlich auch, wenn ein "fremder"
Sender versucht den Empfänger anzusteuern).
Also in diesem Fall leider keine Option..
Danke trotzdem für die Mühe,
Tobi
Hallo Tobi,
in 20ms kannst Du 294912 Instruktionen abarbeiten.
ich behaupte mal, dass eine sichere Verschlüsselung in 2ms
realisierbar ist.
Hatte mich schon mal mit Verschlüsselungsalgos die mit
Permutationstabellen gearbeitet haben befasst.
Man muss lediglich die Tabelle ändern (besteht aus 512 Byte oder weniger
wenn Du willst) und evtl. den Algo und schon hast Du Dein "eigenes"
Verschlüsselungssystem.
Ich habe die Anzahl der Instruktionen nicht gezählt, aber für 8 Byte
waren es waren es schätzungsweise weniger als 2000 Instruktionen.
Wieso bleibt das Problem mit der Aktualität der Sequenznummer bestehen?
Die steckt doch im Sendepaket und wird jedes Mal inkrementiert.
MfG
AKtronik
Hi!
Ja, eine einfache Verschlüsselung ist natürlich möglich.
Permutationsalgos etc bringen mir aber (genau wie ein one-time-pad)
nichts, da immer die gleichen Befehle übertragen werden, welche einen
festen Aufbau haben.
Wenn man mehrere Befehle abfängt und vergleicht kommt man sehr schnell
hinter diesen "festen" Algo. Oder meinst du eine andere Methode?
Das Problem mit der aktualität der Sequenznummer bleibt bestehen, da
jeder Empfänger von sich aus erkennen können muss, ob die Nummer noch
aktuell ist.
Beispiel: Wenn ich 3 Empfänger eine Woche lang in Betrieb hatte ist,
sagen wir die Sequenznummer von vorher 1234 auf z.B. 5678 hoch gegangen.
Ein Empfänger der "in der Garage" lag hat jedoch immer noch die interne
Sequenznummer 1234 als "letzte aktuelle" gespeichert.
Ein "Angreifer" könnte aber in der Zwischenzeit ein paar Befehle mit den
Nummern 2345-2390 aufgezeichnet haben die an die 3 im Einsatz
befindlichen Empfänger gerichtet waren.
Sobald ich jetzt den 4. Empfänger aus der Garage hole und dazu stelle
(ohne selbst bereits etwas "neues" gesendet zu haben) könnte der
Angreifer den aufgezeichneten Befehl mit der Sequenznummer 2345
abspielen und genau den Schaltvorgang auslösen, den der Befehl vor einer
Woche eben schonmal (bei einem anderen Empfänger) ausgelöst hat. Die 3
Module die die ganze Zeit da waren würden erkennen das die Sequenznummer
veraltet ist - der neue Empfänger hingegen würde (weil er ja selbst noch
auf dem Stand "1234" ist) die Sequenznummer als neu betrachten und den
Schaltvorgang auslösen - mit allen Konsequenzen für den Anwender..
Dieses Szenario ist natürlich nur bei allgemeinen Befehlen denkbar, die
eben nicht die eindeutige Empfängerkennung beinhalten (= Broadcasts).
Aber genau die benötige ich unter anderem, um Schaltvorgänge wirklich
absolut gleichzeitig auslösen zu können..
- Tobi
P.S: Ich habe mal ausgerechnet: Wenn ich das oben ausgedachte, sichere
Protokoll benutze brauche ich pro Empfänger 100ms um ihn - ohne RTC -
wieder auf die aktuelle Sequenznummer zu bringen. 10 Empfänger pro
Sekunde bedeutet bei max. z.B. 500 Empfängern 50 Sekunden. Das sollte
noch im Rahmen sein, der Empfänger darf dann zwischen Synchronisation
und realem Einsatz eben nicht mehr abgeschaltet werden.
Hallo Tobi,
also wenn Du den Empfänger aus der Garage holst, müsste beim Anschließen
die Sequenznummer z.B. mittels Reset-Taster auf Null gesetzt werden und
den Ausgang offen lassen.
So erlaubst Du dem Empfänger einmalig auf jede Sequenznummer zu
reagieren wenn die abgespeicherte == null ist.
Beim nächsten Befehl initialisiert sich der Empfänger.
Sollte ein Angreifer nun zeitlich vor Deinem Sender alte Befehle
losgeschickt haben, dann setzt Du
den Empfänger wieder auf null, bis der Empfänger auf die neuen Befehle
Deines Senders reagiert.
Dann hast Du den Angreifer ausgeschlossen und kannst die Ausgänge
anschließen.
Der Plain-Befehl ist aufgrund der sich ständig ändernden Sequenznummer
nie gleich.
Die Änderung von nur einem Bit quirlt den Crypt-Befehl, der gesendet
wird, so dermaßen durch, dass ich mir nicht vorstellen kann dass jemand
auf den Algo kommt obwohl er fest ist.
Mfg
AKtronik
Hi!
Genau das "zurücksetzen auf Null" bis es funktioniert ist eben nicht
möglich. Ich muss davon ausgehen das im späteren Einsatz auch Laien mit
dem Ding umgehen wollen die dann eben nicht 3 mal diese Sequenz
ausführen wollen bzw können - zumal dann vielleicht 100 von den Dingern
rumstehen.
Außerdem darf zu KEINER ZEIT ein falscher Befehl angenommen werden, egal
ob das Ding gerade per Reset auf 0 gesetzt wurde oder nicht. Genau das
würde mit der "Reset auf 0"-Methode aber funktionieren.
Aber wie gesagt, wer den kompletten Thread gelesen hat (ich gebe zu, das
ist mittlerweile ganz schön viel geworden) der weiß, das ich die für
mich optimale Lösung bereits gefunden habe. Die Berechnung des Hashes
ist nicht so die große Sache, durch die RTC kann ich die Einschalt- und
Sync-Zeit klein halten und wenn alle Stricke reißen wird die aktuelle
Sequenz per Challenge-Response-Verfahren gesichert eben vom Sender
"geholt".
Danke für die vielen Vorschläge :-)
- Tobi