Java Socket-Verschlüsselung: Wie Absender verifizieren?

Hoeze

Lieutenant
Registriert
Juni 2010
Beiträge
707
Hi,
ich würde gerne einen java-Server schreiben:
  1. Aufbau einer verschlüsselten TCP-Verbindung mit Client-Zertifikaten; Verifizierung des Absenders per RSA-Fingerprint
    (ähnlich einer SSH-Verbindung)
  2. Aushandeln eines symmetrischen Schlüssels
  3. Client kann ohne großen Overhead über UDP verschlüsselte Nachrichten an den Server senden

Allerdings habe ich folgendes Problem:
Angenommen der Client möchte mehrmals das Kommando "Tür offen halten" an den Server senden, dann sieht ja die verschlüsselte Nachricht jedes Mal gleich aus.

Wie verhindere ich am besten, dass ein Angreifer das verschlüsselte Kommando mitschneidet und nun selber senden kann?
Die OpenSSL-Experten werden sich doch bestimmt schon etwas für diesen Fall ausgedacht haben...
 
Hi,

also ich bin bei Leibe kein Open-SSL Experte und auch sonst nur doofer Informatik Student, aber das erste was mir eingefallen wäre, ist das Prinzip von TCP zu kopieren, und einen Nachrichten-Zähler zu implementieren.

Dadurch schreibt der Client: "Nachricht x: Türe offen halten"

Wenn er es erneut senden möchte schreibt er: "Nachricht x+1: Türe offen halten"

Der Server kann es so und so immer dekodieren und mit Überprüfung des Counters (Wenn er selbst mitzählt) auch noch mitgeschnittene und wieder gesendete Nachrichten (Replay-Attacke heißt das glaub ich) erkennen und aussortieren.

Nur ein erster Gedanke, kreuzigt mich ned ;)

Mfg

Saphirim
 
Hoeze schrieb:
Wie verhindere ich am besten, dass ein Angreifer das verschlüsselte Kommando mitschneidet und nun selber senden kann?
Die OpenSSL-Experten werden sich doch bestimmt schon etwas für diesen Fall ausgedacht haben...

Niemals Verschlüsseln ohne Authentisieren. Siehe z.B. hier: https://en.wikipedia.org/wiki/Message_authentication_code
Außerdem könntest du dich auch über Modes Of Operation informieren.
 
Saphirim schrieb:
also ich bin bei Leibe kein Open-SSL Experte und auch sonst nur doofer Informatik Student, aber das erste was mir eingefallen wäre, ist das Prinzip von TCP zu kopieren, und einen Nachrichten-Zähler zu implementieren.


OMG, danke :D
Dass ich da nicht dran gedacht hab...
Ergänzung ()

asdfman schrieb:
Niemals Verschlüsseln ohne Authentisieren. Siehe z.B. hier: https://en.wikipedia.org/wiki/Message_authentication_code
Außerdem könntest du dich auch über Modes Of Operation informieren.

Also ich dachte, über RSA-Keys ist der Client authentifiziert..?
 
Hoeze schrieb:
OMG, danke :D
Dass ich da nicht dran gedacht hab...
Ergänzung ()

Also ich dachte, über RSA-Keys ist der Client authentifiziert..?

Du hast den Artikel nicht gelesen, oder? Hast doch selbst festgestellt, dass der Schlüssel einem Angreifer in deinem Szenario gar nicht bekannt sein muss. Also warum fragst du sowas?

€: Der Nachricht einfach einen Zähler anzuhängen, genügt übrigens nicht. Du musst einen MAC verwenden und wenn die Authentisierung fehlschlägt das komplette Paket verwerfen, ohne es überhaupt zu entschlüsseln. Wenn du Daten entschlüsseln musst, bevor sie authentisiert sind (z.B. um einen Zählerstand zu kontrollieren), hast du verloren.

€2: Ein Artikel für Leute, deren Aufmerksamkeitsspanne selbst für Wikipedia zu kurz ist:
https://codeinsecurity.wordpress.com/2013/04/05/quick-crypto-lesson-why-mac-then-encrypt-is-bad/
 
Zuletzt bearbeitet:
:D Tut mir leid, ich dachte an "Stelle sicher, dass Client auch wirklich Tür öffnen darf"
Dein zweiter Artikel trifft meine Aufmerksamkeitsspanne schon besser :freaky:
 
@asdfman
Danke, das is natürlich der korrekte Ansatz, erinnere mich jetzt wieder an IT-Security und die MACs...
 
So, nach einem Tag Einlesen ist das Ganze anscheinend doch nicht so trivial...

  • Am Einfachsten (auch im Bezug auf Kompatibilität mit anderen Sprachen) ist es wohl, (D)TLS zu verwenden, statt eigene Sachen auszuprobieren
  • Die ganzen HMAC und AES-CBC-Geschichten sind anscheinend nicht so sicher (MAC-then-encrypt)
    => AES-GCM verwenden, ist auch schneller
  • Anscheinend kann java nativ nur sehr wenig Crypto (bspw. nur AES-128, kein GCM in java 7)

Habt ihr irgendwelche Tipps, wie ich am einfachsten (D)TLS-Verbindungen zu Stande bringe?
Ich würde damit gerne bei Java bleiben, wenn machbar. Mich jetzt mit C/++ beschäftigen zu müssen, würd ich gerne vermeiden..

EDIT:
Was haltet ihr von BouncyCastle bzw. WolfSSL?
 
Zuletzt bearbeitet:
Hoeze schrieb:
So, nach einem Tag Einlesen ist das Ganze anscheinend doch nicht so trivial...

Gut, dass du das so schnell erkannt hast. Krypto für den ernsthaften Gebrauch selber basteln ist fast immer eine ganz schlechte Idee.
Das zum Spaß oder als Übung mal selber gemacht zu haben ist natürlich auch wertvoll, aber man muss sich seiner Grenzen bewusst sein.
Zum Beispiel den fehlenden GCM selber zu bauen wäre etwas, das einen ganz allgemein weiter bringt. So lange man das Ergebnis nicht in
die freie Wildbahn entlässt.

Zum Thema brauchbarer Java-Bibliotheken muss ich die Frage aber leider weiterreichen.
 
Zurück
Oben