Frage zur sicheren Client-Server-Kommunikation

CPU

Lieutenant
Registriert
Jan. 2006
Beiträge
704
Hallo,

ich habe eine mehr oder weniger theoretische Frage, mit folgendem Szenario: :)

In einem Rechnernetzwerk gibt es einen Server und zwei Clients auf jedem Client läuft ein Programm, dass ein Datagram-Socket offen hat. Ab und an holt sich der Server Informationen über das Datagram-Socket von jedem Client. Dies geschieht, indem der Server ein Kommando sendet und der Client einen Antwortstring.

Nun wäre es denkbar, dass ein Dritter von einem Rechner aus den anderen kompromitiert, indem er sich als Server ausgibt und das Kommando für Informationen übermittelt und diese dann erhält (es ist nicht so wichtig, dass die Informationen/Befehle im Klartext gesendet werden; viel wichtiger ist, dass der Sender dazu berechtig ist, diese Befehle zu senden und so eine Reaktion des Clients zu erreichen).

Wie kann ich dem entgegenwirken? Ich muss praktisch eine Authentifizierungsmethode finden (vllt. mit private-/public-Key?) - aber welche? :(

CPU :(
 
jupp mit Keys bzw. x509 Zertifkaten, sodass sich Client und Server gegenseitig authentifizieren und eine Übertragung verschlüsselt stattfinden kann. So kann man auch man-in-the-middle Attacken vorbeugen.

Schau mal, ob dein Framework schon eine entsprechende Lösung anbietet. Viele, wie apache Axis2 liefern sowas mit - ist aber oft nicht ganz so einfach einzurichten. Vor allem am Anfang - da gibts ne Lernkurve.
 
Also ich werde das mit Java implementieren ...

CoolHandLuke schrieb:
Übertragung verschlüsselt stattfinden kann.

Darum geht es mir nicht; es kann ruhig jeder Sniffer mitbekommen, was übertragen wird (und dies könnte man ja einfach mit RSA beheben, wenn man es wollte), doch den Befehl vom Server geben - das muss authentifiziert werden und eindeutig dem Server zugeordnet werden können.

Gibt es dafür evtl. auche eine "einfachere" Lösung *mmmmh*, da es sich hier nicht um eine offizielle Signierung handeln wird? Hier wird auch mit Authentifizierungsschlüsseln gearbeitet: http://italc.sourceforge.net/wiki/i...#Authentifizierungs-Schl.C3.BCssel_einrichten

CPU
 
Zuletzt bearbeitet:
CPU schrieb:
Nun wäre es denkbar, dass ein Dritter von einem Rechner aus den anderen kompromitiert, indem er sich als Server ausgibt und das Kommando für Informationen übermittelt und diese dann erhält (es ist nicht so wichtig, dass die Informationen/Befehle im Klartext gesendet werden; viel wichtiger ist, dass der Sender dazu berechtig ist, diese Befehle zu senden und so eine Reaktion des Clients zu erreichen).

Wie kann ich dem entgegenwirken? Ich muss praktisch eine Authentifizierungsmethode finden (vllt. mit private-/public-Key?) - aber welche?

Das ist, wie bereits von CoolHandLuke beschrieben mit Zertifikaten möglich. Zertifikate in Verbindung mit asymmetrischen Verschlüsselungen, z.B. RSA, garantieren das nur dein Server die Clients abfragen kann.

Die Echtheit des Zertifikats wird bei der Zertifizierungsstelle ermittelt. Auch ein Zetifikat garantiert nicht zu 100 % die Sicherheit, aber es ist das Beste was du erreichen kannst.

Das Zertifikat dient der eindeutigen Authentifizierung.

Du kannst aber auch eventuell komplett auf die Authentifizierung verzichten. Wenn du den Server von Haus aus mit dem Private Key ausstattest und den Klienten mit dem Public Key.

Ein falscher Server kann nun Daten von einem Clienten abfragen, aber der Client verschlüsselt jede Nachricht mit dem Public Key, den nur der echte Server entschlüsseln kann.

Da du auf Java zurückgreifst, kannst du einen Blick darauf werfen.

http://www.codeplanet.eu/tutorials/java/7-aes-und-rsa-in-java.html
 
Stefan_Sch schrieb:
Du kannst aber auch eventuell komplett auf die Authentifizierung verzichten. Wenn du den Server von Haus aus mit dem Private Key ausstattest und den Klienten mit dem Public Key.

Ein falscher Server kann nun Daten von einem Clienten abfragen, aber der Client verschlüsselt jede Nachricht mit dem Public Key, den nur der echte Server entschlüsseln kann.

Ja, damit wird die Information vom Client verschlüsselt! Mir geht es aber eigendlich darum, dass der Befehl für diese Information vom Server an den Client "zertifiziert" wird (hört sich konfus an, ist aber richtig)!

Ich habe mir dennoch folgendes überlegt (da ich ja im Internet suche und brav die Wikipedia-Artikel lese :)):

Also, Server erhält einen private-Key und alle Clients einen public-Key. Die Schlüssel werden ab und an gewechselt. Um am Anfang sicherzustellen, dass der public-Key auch der richtige Key ist, wird dieser vom Server generiert und dann über einen USB-Stick etc. vom Admin beim Installieren der Anwendung mitgegeben. Nun kann der Client Daten verschlüsseln und an den Server übermitteln, der diese entschlüsseln kann.
Genau an dieser Stelle kommt AES ins Spiel: AES erstellt ein Passwort und sendet dies mit dem public-Key verschlüsselt an den Server; dieser verschlüsselt den Befehl mit AES und sendet diesen an den Client. Der Client kann den Befehl entschlüsseln und lesen. Bei jeder Transaktion oder alle x Minuten wird der Schlüssel des Clienten (AES) gewechselt.

Damit müsste doch eigendlich mein Problem gelöst sein, oder? Außerdem: eine 100%-ige Lösung gibt es sowieso nicht. Da hilft nur öfteres Schlüsselwechseln!

CPU :)
 
Zuletzt bearbeitet:
Also zuerst mal vorweg, bitte Zitat korrigieren. ;)

CPU schrieb:
Ja, damit wird die Information vom Client verschlüsselt! Mir geht es aber eigendlich darum, dass der Befehl für diese Information vom Server an den Client "zertifiziert" wird (hört sich konfus an, ist aber richtig)

Du möchtest das die Befehle an den Klienten nur vom Server gegeben werden können?

Erklär mal genauer was du erreichen möchtest.

CPU schrieb:
Also, Server erhält einen private-Key und alle Clients einen public-Key. Die Schlüssel werden ab und an gewechselt.

Warum sollen die Schlüssel gewechselt werden?

CPU schrieb:
Um am Anfang sicherzustellen, dass der public-Key auch der richtige Key ist, wird dieser vom Server generiert und dann über einen USB-Stick etc. vom Admin beim Installieren der Anwendung mitgegeben. Nun kann der Client Daten verschlüsseln und an den Server übermitteln, der diese entschlüsseln kann.

Über USB Stick stellt natürlich die Identität auch sicher.

CPU schrieb:
Genau an dieser Stelle kommt AES ins Spiel: AES erstellt ein Passwort

AES erstellt kein Passwort, weil AES ein symmetrischer kryptographischer Algorithmus ist und kein Passwortgenerator. ;)

CPU schrieb:
und sendet dies mit dem public-Key verschlüsselt an den Server; dieser verschlüsselt den Befehl mit AES und sendet diesen an den Client. Der Client kann den Befehl entschlüsseln und lesen. Bei jeder Transaktion oder alle x Minuten wird der Schlüssel des Clienten (AES) gewechselt.

Wozu der ständige Wechsel?

CPU schrieb:
Da hilft nur öfteres Schlüsselwechseln!

Warum?
 
Ich dachte, dass es sicherer ist, wenn ab und an mal die Schlüssel gewechselt werden :)

@AES erstellt kein Passwort:
Ist mir auch klar, aber ich dachte da noch in JAVA und dort muss man eine AES-Instanz erzeugen etc. pp. und irgendwann kann man eine Methode wie generateKey() aufrufen.

Damit wäre die Sache dann wohl erledigt und ich setzte sie so um!

CPU :D
 
Du hast das Zitat mit dem falschen Namen immer noch nicht korrigiert... :rolleyes:

CPU schrieb:
Ich dachte, dass es sicherer ist, wenn ab und an mal die Schlüssel gewechselt werden

Nö, das System wird durch häufige Schlüsselwechsel eher noch unsicherer.

CPU schrieb:
@AES erstellt kein Passwort:
Ist mir auch klar, aber ich dachte da noch in JAVA und dort muss man eine AES-Instanz erzeugen etc. pp. und irgendwann kann man eine Methode wie generateKey() aufrufen.

Wozu willst du nun auch noch AES verwenden? Das macht keinen Sinn.
 
Also, das Passwort mit dem der Befehl mittels AES verschlüsselt wird, wird mit pulic-Key verschlüsselt an den Server gesendet, der das Passwort entschlüsselt, den Befehl mit AES und diesem Passwort verschlüsselt und an den Client sendet, welcher dann mit AES und dem Passwort die Nachricht entschlüsselt und ausführt. Dabei kann ein potetieller Angreifer nichts mitbekommen! Und es wird somit sichergestellt, dass nur der Server Befehle gibt ... okay?

P.S.: Mit dem Zitat zufrieden ;-)?
 
CPU schrieb:
Also, das Passwort mit dem der Befehl mittels AES verschlüsselt wird, wird mit pulic-Key verschlüsselt an den Server gesendet, der das Passwort entschlüsselt, den Befehl mit AES und diesem Passwort verschlüsselt und an den Client sendet, welcher dann mit AES und dem Passwort die Nachricht entschlüsselt und ausführt. Dabei kann ein potetieller Angreifer nichts mitbekommen! Und es wird somit sichergestellt, dass nur der Server Befehle gibt ... okay?

Das habe ich schon verstanden, aber darum ging es nicht. Du erklärst hier die Lösung ohne Problem.

Was für eine Anwendung soll das hier werden?

Schickt der Server Befehle an die Klienten? Ja oder Nein?

Schicken die Klienten Daten an den Server? Ja oder Nein?

Werden von den Klienten daraufhin Operationen durchgeführt, die nur vom authentifizierten Server in Auftrag gegeben werden dürfen? Ja oder Nein?

Falls Daten an den Server gesendet werden, sind diese vertraulich? Ja oder Nein?

Wenn das Problem nicht bekannt ist, muss man sich auch nicht über eine Lösung unterhalten.

CPU schrieb:
P.S.: Mit dem Zitat zufrieden ;-)?

Ja. ;)
 
Es gibt Clienten und einen Server. Der Server sammelt sagen wir 3x am Tag Daten über den Zustand der Rechner (sofern diese angeschaltet sind). Dazu sendet der Server einen Befehl und erhält vom Client eine Antwort.

Für mein spezielles Szenario (das ich hier nicht so genau ausrollen kann und will) ist es von besonderer Bedeutung, dass die bzw. der Befehl vom Server auch wirklich vom Server gegeben wird und nicht von einer dritten Person. Der übermittelte Inhalt ist hierbei nur nebensächlich ...

Mein Problem war, dass ich keine Ahnung hatte, wie man prüft, ob ein Befehl wirklich vom Server kam und ausgeführt werden soll. Da Zertifikate zu komplex (u. kostenpflichtig) für dieses Programm sind habe ich mir diese Kombination aus einem asymetrischem (RSA) und symetrischen (AES) überlegt um dies sicherzustellen und somit mein Problem gelöst.

Es steht trotzdem hier zur Diskussion, damit mir kein grober Modellierungsfehler unterläuft und dirket nach der Release ein Security-Update nötig ist!

CPU
 
«Es gibt Clienten und einen Server. Der Server sammelt sagen wir 3x am Tag Daten über den Zustand der Rechner (sofern diese angeschaltet sind). Dazu sendet der Server einen Befehl und erhält vom Client eine Antwort.»

Hmmm wäre es nicht umgekehrt logischer: Falls aktiv, senden die Clients einmal pro Tag die Daten an den Server, der einfach nur passiv auf Anfragen von außen reagiert. Clients müssen sich an ihm über ihre Zertifikate authentifizieren.
 
CPU schrieb:
Es gibt Clienten und einen Server. Der Server sammelt sagen wir 3x am Tag Daten über den Zustand der Rechner (sofern diese angeschaltet sind). Dazu sendet der Server einen Befehl und erhält vom Client eine Antwort.

Für mein spezielles Szenario (das ich hier nicht so genau ausrollen kann und will) ist es von besonderer Bedeutung, dass die bzw. der Befehl vom Server auch wirklich vom Server gegeben wird und nicht von einer dritten Person. Der übermittelte Inhalt ist hierbei nur nebensächlich ...

Exzellent! Hättest du diese Angaben im Eingangsbeitrag gemacht, hätte sich so mancher Wortwechsel erübrigt. ;)

Jetzt stellen sich noch 2 Fragen. Sollen die Daten, die der Klient an den Server schickt auch verschlüsselt sein?

Läuft Kommunikation über TCP oder UDP?

Welche Befehle sendet der Server an die Clienten? Eine Datenanfrage etwa?

CPU schrieb:
Mein Problem war, dass ich keine Ahnung hatte, wie man prüft, ob ein Befehl wirklich vom Server kam und ausgeführt werden soll. Da Zertifikate zu komplex (u. kostenpflichtig) für dieses Programm sind habe ich mir diese Kombination aus einem asymetrischem (RSA) und symetrischen (AES) überlegt um dies sicherzustellen und somit mein Problem gelöst.

Zertifikate beruhen auf RSA, sie sind daher nicht komplexer. Zertifikate dienen lediglich der Authentfizierung unbekannter Stellen.

Ich nehme aber an das du den Server und Client schreibst, also gibt es keine unbekannten Stellen.

Du hattest auch geschrieben das du per USB direkt auf die Clienten zugreifst, d.h. die Identität von dir muss nicht erst durch eine Zertifizierungsstelle bescheinigt werden, daher brauchst du keine Zertifikate.
 
CPU schrieb:
Ab und an holt sich der Server Informationen über das Datagram-Socket von jedem Client.

Sagt das nicht schon aus, dass die Kommunikation über UDP verläuft? Die Befehle lauten beispielsweise (Server an Client):
Code:
show-pc-data;
und der Client antwortet dann:
Code:
pc-data; length: 5; md5sum: 7hgf4gh564dvbhg4hr5lo9gs3gde7hnb;
onloged_user=benutzer1
status=okay
...

Genau ich schreibe eine Server- und eine Client-Anwendung.

Ich meinte, dass ich z.B. einen USB-Stick benutzen kann, um den public-Key zum Client zu transportieren. Denn wenn der Client den allerersten public-Key vom Server beziehen würde, wäre es möglich, dass ein Hacker einen falschen public-Key dem Client übergibt und diesen so konrollieren kann.

CPU
 
CPU schrieb:
Sagt das nicht schon aus, dass die Kommunikation über UDP verläuft? Die Befehle lauten beispielsweise (Server an Client):

Das hatte ich bereits gelesen, dennoch kann es sein das ein anderer Teil über TCP läuft.

Für SSL benötigst du aber TCP.

CPU schrieb:
Genau ich schreibe eine Server- und eine Client-Anwendung.

Ich meinte, dass ich z.B. einen USB-Stick benutzen kann, um den public-Key zum Client zu transportieren. Denn wenn der Client den allerersten public-Key vom Server beziehen würde, wäre es möglich, dass ein Hacker einen falschen public-Key dem Client übergibt und diesen so konrollieren kann.

Warum lieferst du den Clienten nicht gleich mit dem Public Key aus?
 
Zurück
Oben