Forum: Mikrocontroller und Digitale Elektronik Sichere Kommunikation 1:n?


von Tobias Hagemeier (Gast)


Lesenswert?

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..

von Peter (Gast)


Lesenswert?

Hallo,
kennen die System die Urzeit? wenn ja könnte man statt der Sequenznummer 
die Zeit übertragen.

von Dan M. (killler07)


Lesenswert?

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

von Arc N. (arc)


Lesenswert?


von 11833 (Gast)


Lesenswert?

http://en.wikipedia.org/wiki/KeeLoq
http://de.wikipedia.org/wiki/KeeLoq

keeloq ist zwar geknackt, prinzip könnte aber für dich interessant sein.

von Tobias Hagemeier (Gast)


Lesenswert?

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

von Tobias Hagemeier (Gast)


Lesenswert?

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

von Arc N. (arc)


Lesenswert?

Die englische Wikipedia bietet einen besseren Überblick über MACs als 
die DE-Variante...
http://en.wikipedia.org/wiki/Message_Authentication_Code

von so nicht (Gast)


Lesenswert?

Mega16 ? Der ist zu klein fuer alles in dieser Richtung, wenn man sonst 
noch was machen will.

von Tobias Hagemeier (Gast)


Lesenswert?

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 ;)

von Simon K. (simon) Benutzerseite


Lesenswert?

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).

von Gast (Gast)


Lesenswert?

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

von Tobias Hagemeier (Gast)


Lesenswert?

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..

von Tobias Hagemeier (Gast)


Lesenswert?

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?

von Tobias H. (hse)


Lesenswert?

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

von Ak T. (aktronik)


Lesenswert?

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

von Tobias H. (hse)


Lesenswert?

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

von Michael (Gast)


Lesenswert?

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

von Tobias H. (hse)


Lesenswert?

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

von Ak T. (aktronik)


Lesenswert?

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

von Tobias H. (hse)


Lesenswert?

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.

von Ak T. (aktronik)


Lesenswert?

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

von Tobias H. (hse)


Lesenswert?

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

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.