Forum: Mikrocontroller und Digitale Elektronik RFM12 Übertragung Verschlüsseln?


von Steffen (Gast)


Lesenswert?

Hallo Gemeinde,
ich nutze die RFM Module für eine Fernbedienung. Nun möchte ich nicht 
wirklich immer den gleichen Code übertragen. (Falls mal einer die 
Übertragung mit loggt)Wie kann man es anstellen, das man ein wenig 
Sicherheit hinbekommt? Ich hab schon versucht über verschiedene 
gespeicherte Werte eine Art Senderprüfung zu machen. Aber egal wie ich 
überlege, wenn man die Daten mit loggt und umrechnet kommt man recht 
schnell drauf wie es gemacht wurde. Ich sende mit RFM02 und empfange mit 
RFM01.
Danke für eure Vorschläge

von chris (Gast)


Lesenswert?


von Stone (Gast)


Lesenswert?

Ein Kumpel von mir hat das mit Challenge-Response-Authentifizierung 
gemacht
http://de.wikipedia.org/wiki/Challenge-Response-Authentifizierung

Dafür braucht man natürlich hin und Rückkanal

Gruß Matthias

von kopfkratzer (Gast)


Lesenswert?

kopfkratz
Also ohne Handshake oder zwei identische Taktgeber die auf eine 
Pseudozufallsreihe synchron zugreifen wird das nix.
Am sinnvollsten RFM01 und RFM02 gegen zwei RFM12 austauschen und einen 
Handshake mit generierten keys am Anfang durchführen.
PGP&Co. sürften wohl flachfallen ;-)
Außer natürlich Du hast zwei dicke ARM oder MIPS als µC im Einsatz ?

von Marcus W. (marcusaw)


Lesenswert?

Bei den Übertragungslängen dürfte ein Hashen mit Rollingcode vollkommen 
ausreichen. Ein 3-byte Wort zur Hasherzeugung und ab dafür. Schließlich 
hat deine Fahrzeug-FB auch keinen Arm oder MIPS eingebaut.

: Bearbeitet durch User
von Steffen (Gast)


Lesenswert?

danke für die Anregungen. Ich möchte einen gebräuchlichen Atmega 
verwenden. Ich denke das wird Rolling Code werden. Hierbei habe ich 
versucht Informationen bei Google zu finden. Leider ohne Erfolg. Wie 
errechne ich mir Rolling Code?

von Marcus W. (marcusaw)


Lesenswert?

Der Gag am Rollingcode ist, dass der Sender dem Empfänger beim Senden 
einer Nachricht bereits den Hash der nächsten Nachricht übermittelt. Wie 
er auf diesen Hash kommt, musst du mit einem (von dir erdachten) 
Algorithmus implementieren - auf beiden Seiten.

Ein einfacher Verschlüsselungsalgorithmus war z.B. früher schon immer 
einfach Buchstaben zu verschieben.

Zum Beispiel um (+) 3 Stellen:
Aus A wird D
Aus B wird E
etc etc

Beim Rollingcode müsstest du dann deinem Empfänger praktisch nur 
mitteilen, um vieviel die nächste
Nachricht verschoben wird - du sendest also in der verschlüsselten 
Nachricht den Wert als letzes, mittleres etc Byte mit - wichtig ist, 
dass der Empfänger weiß, wo er suchen muss.

Das ganze konzept lässt sich beliebig ausbauen - durch einfache 
mathematische Operationen. Sende statt einem Byte drei an verschiedenen 
Stellen - schon hast du exponenziell stärkere Verschlüsselung.

Schau dir einfach mal den Wikipedia-Artikel durch:
http://de.wikipedia.org/wiki/Verschl%C3%BCsselung

: Bearbeitet durch User
von kopfkratzer (Gast)


Lesenswert?

Steffen schrieb:
> Wie
> errechne ich mir Rolling Code?

Du erzeugst Dir einfach eine Liste mit Pseudozufallszahlen die Du in 
Sender und Empfänger ablegst.
Das ist eine symmetrische Verschlüsselung ohne Handshake, ginge also 
auch mit Deiner aktuellen Hardware.
Also z.B. eine Tabelle mit 64 Werten die sowohl in Deinem Sender als 
auch Deinem Empfänger identisch sind.
Dann schreibst Du einen einfachen Code der diese Liste in beiden Geräten 
identisch ansteuert und nimmst einen einfachen Hash oder XOR um Deine 
Daten damit zu "verschlüsseln".
Nachdem Datenpaket #1 mit dem dritten Eintrag in der Liste abgeschickt 
wird berechnet sowohl der Sender als auch Empfänger den nächsten Eintrag 
z.B. 60 von der Liste und bei der nächsten Übertragung wissen beide 
welchen Schlüssel man benötigt.
Klar geworden ?

von Mr. X (Gast)


Lesenswert?

kopfkratzer schrieb:
> Klar geworden ?

Nicht ganz. Was passiert, wenn der Sender den vereinbarten Code 
versendet und der Empfänger das nicht mit bekommt?
Der Empfänger wartet dann ewig auf die Nr.60 und der Sender ahnt nichts 
von dem Mißgeschick.

von Steffen (Gast)


Lesenswert?

Ich bin eben bei den Verschlüsselungsarten. Ist gar nicht so einfach. 
Ich werd mich erstmal belesen. Mal schauen was sich dann ergibt.

von Master Key (Gast)


Lesenswert?

Mr. X schrieb:
> Was passiert, wenn der Sender den vereinbarten Code
> versendet und der Empfänger das nicht mit bekommt?

Dann funktionierts nicht mehr. Deshalb sendet der Sender nicht nur den 
nächsten Code sondern z.B. die Nächsten 5 oder 10 Codes.
Dann kann der Empfänger vergleichen, ob er wegen des Verpassens einer 
Übertragung eine Übereistimmung mit einem der Folgecodes bekommt. Findet 
er eine Übereinstimmung, so ist er wieder synchron zum Sender. Findet er 
keine, so muss der Sender neu eingelernt werden.
Bei manchen Autschlüsseln steht in der Anleitung, dass man nicht allzu 
oft die Knöpfe drücken soll, wenn das Auto nicht in Reichweite ist, da 
ansonsten der Schlüssel neu eingelernt werden muss.

von BesserAlsNichts (Gast)


Lesenswert?

1
#include <avr/io.h>
2
#include <stdbool.h>
3
#include "stdlib.h"
4
5
typedef unsigned long DWORD;
6
7
8
// - Wichtig!
9
//   RandomReleaseNumber muss vor jedem Flashen des Senderprogramms
10
//   zufällig gewählt werden (sonst würden sich wegen gelöschtem
11
//   EEProm die vorherigen Sendedaten wiederholen).
12
const DWORD RandomReleaseNumber = 0x12fdf454;
13
14
void Crypter(DWORD* Data, char Count)
15
{
16
  srandom(Data[0]); // beim AVR die 32 Bit Version von srand() 
17
  for(int i=1; i<Count; i++)
18
  {
19
    Data[i] ^= random();
20
  }
21
}
22
23
void EncodeData(DWORD* Data, char Count)
24
{ 
25
  static DWORD EEProm_Seed    = 0;
26
  static DWORD EEProm_Counter = 0;
27
  Data[0] = EEProm_Seed;
28
  Data[1] = EEProm_Counter;
29
  Data[2] = RandomReleaseNumber;
30
  Crypter(Data, Count); // verschlüsseln
31
  EEProm_Seed = random(); // beim AVR die 32 Bit Version von rand() 
32
  EEProm_Counter++;
33
}
34
35
bool DecodeData(DWORD* Data, char Count, bool DoSynconize)
36
{ 
37
  static DWORD EEProm_Counter = 0;
38
  static DWORD EEProm_ID      = 0;
39
  Crypter(Data, Count);
40
  if(!DoSynconize)
41
  {
42
    // passt der "Geräte-Code"?
43
    if(Data[2]!=EEProm_ID) return false; // nein -> ungültig
44
    // passt der Zählerstand (nur die nächsten 65536 Codes sind erlaubt)?
45
    DWORD dCounter = Data[1]-EEProm_Counter;
46
    if(dCounter==0) return false;
47
    if(dCounter>0xffff) return false;
48
  }
49
  // es liegen gültige Nutzdaten vor (FunkDaten[3..])
50
  EEProm_Counter = Data[1];
51
  EEProm_ID      = Data[2];
52
  return true;
53
}
54
55
int main(void)
56
{ 
57
  while(true)
58
  {
59
    // - CryptedData[]
60
    //   Das Array enthält die zu sendenden bzw. die empfangenen Daten
61
    //   Die ersten drei DWORDs sind reserviert. Mit dem vierten DWORD
62
    //   beginnen die Nutzdaten.
63
    DWORD CryptedData[4]; // 4 = 3+1 -> die Nutzdaten sind ein DWORD 
64
65
    // - Sender-SourceCode
66
    {
67
      CryptedData[3] = 12345789; // Nutzdaten
68
      EncodeData(CryptedData, sizeof(CryptedData)/sizeof(*CryptedData));
69
      // CryptedData[] wird gesendet...
70
    }
71
72
    // - Empfänger-SourceCode
73
    {
74
      // ...CryptedData[] wird empfangen
75
76
      // - Variable "SynchronizeKeyPressed"
77
      //   Beim Empfänger müsste einmalig eine Taste gedrückt werden, damit
78
      //   sich der Empfänger auf die Senderkodierung einstellen kann.
79
      static bool SynchronizeKeyPressed = true; // die "Sync-Taste"
80
81
      if(DecodeData(CryptedData, 
82
                    sizeof(CryptedData)/sizeof(*CryptedData),
83
                    SynchronizeKeyPressed))
84
      {
85
        // es wurden Nutzdaten empfangen... (CryptedData[3])
86
      }
87
88
      SynchronizeKeyPressed = false;  // Empfänger nun Synchron
89
    }
90
91
  }
92
}

Ich hab ein kleines Beispielprogramm für einen ATTiny geschrieben. Der 
Sende- und  Empfangscode wurde in einem Quelltext zusammengefasst. 
Außerdem müssten die EEProm_*-Variablen natürlich nicht "static" sondern 
im EEProm liegen.

Die Verschlüsselung ist sehr einfach gehalten. Es wird die random()-bzw. 
srandom()-Funktion zur Generierung der Zufallszahlenkette verwendet. 
Wenn der Hacker den Quelltext kennt, lässt sich die Verschlüsselung also 
einfach knacken. Außerdem ist die Schlüssellänge mit 32 Bit gering. Ein 
"richtiger" Verschlüsselungsalgorithmus und eine hohe Bittiefe sind nach 
meiner Meinung aber nicht unbedingt nötig, da auch dann noch ein Angriff 
per Störsender-Methode möglich wäre. Also wenig mehr Sicherheit für 
deutlich mehr (statt derzeit 800 Bytes) Programmcode.

Ein Angriff über das Senden von zufälligen Codes ist praktisch (48Bit) 
unmöglich. Falls 100 Jahre jede Sekunde 100 Codes gesendet werden würde, 
dann wäre das mit 99.9%iger Wahrscheinlichkeit vergeblich.
Der Angriff über das Senden eines älteren Codes wäre noch erfolgloser 
(31Bit), da ein Sendecode erst nach mehreren Milliarden Übertragungen 
wiederholt wird.

Wem das Senden gleicher Codes etwas zu unsicher ist, der kann hiermit 
auf einfache Weise deutlich mehr Sicherheit erreichen.

von Jens (Gast)


Lesenswert?

Hallo Steffen!

Ich hatte mir mal ein simples Verschlüsselungssystem aufgebaut, 
vielleicht kannst Du es gebrauchen. Der Aufbau sieht in etwa so aus 
(Abweichungen sind erwünscht).
4 Byte = Seriennummer
x Byte = Nutzdaten
2 Byte = freilaufender Zähler (oder Uhrzeit, oder Werte aus einer 
Tabelle)
Daraus erstellst Du eine 32-Bit Prüfsumme und hängst die 4 Byte der 
Prüfsumme mit an. Der zu sendende String ist so also 11 Bytes lang (bei 
1 Byte Nutzdaten) und der String ändert sich auch bei jeder Übertragung. 
Das funktioniert ziemlich gut und solange keiner Deine Hardware „knackt“ 
ist die Übertragung auch relativ sicher. Die Auswertung des Strings 
funktioniert dann in etwa so:
1.) Überprüfung ob CRC32 und Daten übereinstimmen
2.) Überprüfe die Seriennummer
3.) Nutzdaten verarbeiten
Die 2 Bytes des freilaufenden Zählers kannst Du ignorieren. Wenn Du 
diese nutzen möchtest, dann kannst Du darin auch den Rollcode 
verstecken...

LG Jens

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.