Sicherung der Kommunikation zwischen begrenzten eingebetteten Systemen

Jan 04 2021

Ich versuche derzeit, die Kommunikation über einen begrenzten physischen Kommunikationskanal auf einem eingebetteten System zu verbessern.

Das Szenario

Ich denke, das System ist eher typisch für kleine eingebettete Anwendungen:

  • Bei den beteiligten eingebetteten Systemen handelt es sich um kleine Mikrocontroller ohne Betriebssystem, von denen angenommen werden kann, dass sie sich in einer sicheren physischen Umgebung befinden. Der Verbindungskanal ist für Angreifer physisch zugänglich. Sie können Nachrichten nach Bedarf stören.

  • Verschiedene Kommunikationskanäle sind möglich: zB RS485 oder RS232. Es gibt ein grobes Protokoll, das Dinge wie Adressierung und grobe Integrität behandelt (z. B. CRC16 für Bitflips), auf denen wir aufbauen können. Stellen Sie sich das als langsames TCP vor.

  • Jeder Kommunikationspartner kennt ein Stammzertifikat, das als Zertifizierungsstelle fungieren kann und über ein eigenes eindeutiges Zertifikat (+ Schlüssel) verfügt. Zertifikate sind selbstsignierte, elliptische Kurve prime256v1

  • Für diese Systeme steht die mbedTLS-Bibliothek zur Verfügung (mit DH, AES, ..).

  • Meistens ist kein Internet verfügbar.

  • Die Systeme können Zeit behalten und ausreichende Zufallszahlen erstellen

Ich möchte Privatsphäre, Authentizität und Integrität erreichen.

Wie es gelöst werden könnte

Eine Regel in kryptografischen Protokollen ist, sie niemals selbst zu implementieren. Leider habe ich nichts gefunden, was zu diesem Anwendungsfall passt.

Ich habe auch vorhandene Fragen durchgesehen, aber nichts lieferte die vollständige Lösung, nach der ich gesucht hatte.

Schließlich wird in dieser Antwort die Implementierung eines eigenen Protokolls als letzte Option angegeben.

Aus diesem Grund habe ich die unten beschriebene Lösung gefunden - bin mir aber nicht ganz sicher. Ich habe mich auf diese Antwort zur Authentifizierung eines Diffie-Hellmann-Schlüsselaustauschs , diese Antwort zur Überprüfung der Integrität und diesen Thread konzentriert, der mir einige Ideen zur Implementierung eines solchen Protokolls gibt .

Protokoll zur Sicherung der Kommunikation

Als erstes wird zufällig ein symmetrischer Schlüssel K generiert. Als Erstes wird eine Handshake-Nachricht gesendet. Es hat die folgenden Felder:

Feld Beschreibung
DH Der Diffie-Hellmann-Schlüsselaustausch msg g K.
Cert Das Zertifikat (-chain) des sendenden Geräts
MsgIdNonce Ein zufälliger 64-Bit-Wert
Unterschrift Eine Signatur der vollständigen Nachricht mit dem privaten Schlüssel von Cert

Beide Geräte senden (und empfangen) eine solche Nachricht.

Wenn eine Nachricht empfangen wird, geschieht Folgendes:

  1. Überprüfen Sie, ob das Zertifikat von der erwarteten Zertifizierungsstelle signiert ist (muss in der Kette sein).
  2. Überprüfen Sie, ob msg ordnungsgemäß mit cert und seinem Schlüssel signiert ist

Wenn diese Überprüfungen erfolgreich sind, werden die gesendeten und empfangenen DH g K- Nachrichten verwendet, um einen symmetrischen Schlüssel zu berechnen.

Ab diesem Zeitpunkt können Anwendungen mit AES-CBC verschlüsselte Nachrichten senden. Da Nachrichten relativ häufig verloren gehen können, ist IV immer in der Nachricht enthalten.

Dies ist das Nachrichtenformat:

Feld Beschreibung Verschlüsselt
IV Anfänglich zufällig IV für AES Nein
MsgIdNonce Handshake / Last MsgIdNonce + 1 oder + 2 Ja
Anwendungsdaten Die zu schützenden Daten / Befehle Ja
CMAC auf 64 Bit abgeschnitten MAC zur Überprüfung der Integrität Ja

Damit eine Nachricht akzeptiert wird, muss sie vorliegen

  1. Lassen Sie die erwartete MsgIdNonce (1 oder 2 über der zuletzt empfangenen) eine Wiederholungsangriffe verhindern und 1 Nachricht verlieren
  2. Haben Sie einen gültigen CMAC - verhindern Sie Angriffe auf die Integrität
  3. Empfangen werden max. T Sekunden nach der letzten Nachricht - Verhindert Verzögerungsangriffe

Wenn etwas nicht wie erwartet ist, wird Handshake erneut gesendet, und die Nachricht wird erneut mit neu ausgetauschten Parametern gesendet.

Fragen

Bin ich auf dem richtigen Weg oder sollte ich etwas ganz anderes ausprobieren?

Bietet dies meine Sicherheitsziele oder vermisse ich hier offensichtliche Schwachstellen?

Kann das funktionieren?

Ich hoffe, Sie können mir und anderen Embedded-Ingenieuren bei ähnlichen Problemen helfen!

Antworten

2 poncho Jan 04 2021 at 23:18

Eine Regel in kryptografischen Protokollen ist, sie niemals selbst zu implementieren. Leider habe ich nichts gefunden, was zu diesem Anwendungsfall passt.

Haben Sie DTLS in Betracht gezogen ? Das versucht, das gleiche Problem zu lösen (mit Ausnahme von Zeitstempeln; dies könnte durch Einfügen des Zeitstempels in das Datagramm hinzugefügt werden) und hat bereits einige Überlegungen angestellt. Eine andere Möglichkeit wäre IPSec; DTLS nähert sich jedoch eher der Lösung des Problems (es sei denn, der von Ihnen geschützte Datenverkehr ist IP-Verkehr).

Das heißt, hier sind einige Gedanken zu dem Protokoll, das Sie skizziert haben:

  • Was passiert, wenn zwei aufeinanderfolgende Nachrichten gelöscht werden (z. B. falsch empfangen)? Werden die beiden Seiten erkennen, was passiert ist, oder werden sie alle nachfolgenden Nachrichten löschen (aufgrund der Regel "Nonce muss nicht mehr als 2 erhöhen")?

  • Angenommen, sie versuchen einen erneuten Schlüssel, wie ist dies koordiniert? Was passiert mit Nachrichten, die mit dem alten Schlüssel verschlüsselt wurden, wenn eine Seite glaubt, dass sie noch nicht neu verschlüsselt wurden, und die andere Seite glaubt, dass sie es noch nicht getan haben? Wir finden es im Allgemeinen nützlich, ein "Welcher Schlüssel, unter dem dies verschlüsselt ist" -Tag in den Chiffretext aufzunehmen (in DTLS ist dies die "Epoche").

  • Kann Ihr Kommunikationskanal Nachrichten neu anordnen? Ich vermute, dass dies in Ihrem Fall nicht möglich ist, aber wenn dies möglich ist, sollten Sie darüber nachdenken, wie damit umgegangen werden soll.

  • Was passiert, wenn jemand eine vorherige (gültige) Handshake-Nachricht einfügt? Wie wird das die Dinge verwirren?

  • Im Datenverschlüsselungspfad verwenden Sie die CBC-Verschlüsselung und die CMAC-Integrität. Dies ist zwar eine praktikable Lösung, sie ist jedoch anfällig für verschiedene Padding-Angriffe, wenn sie nicht richtig integriert sind. Gegenwärtig wird ein AEAD-Modus (wie GCM oder Chacha20 / Poly1305) verwendet, der beides kann.

  • Ist der verschlüsselte Verkehr unidirektional oder bidirektional? Wenn der Datenverkehr in beide Richtungen verläuft, verwenden Sie denselben Schlüsselsatz, um beide Datenverkehrsgruppen zu schützen?

  • "Wenn etwas nicht wie erwartet ist, wird Handshake erneut gesendet, und die Nachricht wird erneut mit neu ausgetauschten Parametern gesendet." - wie soll das gehen? Wenn der Empfänger feststellt, dass ihm die Nachricht nicht gefällt, woher weiß der Absender, dass er sie erneut senden soll?