Frage über sichere Chat Kommunikation (RSA, AES-256)

  • Allgemein

Es gibt 12 Antworten in diesem Thema. Der letzte Beitrag () ist von n1nja.

    Frage über sichere Chat Kommunikation (RSA, AES-256)

    Hallo,

    ich habe eine Frage über Verschlüsselungen und zwar möchte ich den Chat von kevin89 ([VB.NET] Multiserver (TCP)) benutzen
    und dabei die Kommunikation verschlüsseln.
    Zum Schlüsselaustausch benutze ich RSA und dann AES als symmetrische Verschlüsselung für
    die weitere Kommunikation.
    Soweit so gut, ich habe es auch schon eingebaut und getestet und es funktioniert auch alles (hab
    auch mit Wireshark gelauscht :D), doch jetzt habe ich eine Frage über die Theorie. Denn dazu habe
    ich zwei Lösungen und frage mich jetzt welche die bessere ist. (vielleicht sind auch gar keine richtig,
    freue mich über konstruktive Kritik)

    Lösung 1)
    Der Client generiert den Public- und Privatekey und schickt den Publickey unverschlüsselt an den Server.
    Der Server generiert mithilfe eines Passwortzufallsgenerator das Passwort für die sysmmetrische Verschlüsselung.
    Dieses Passwort verschlüsselt er mit dem Publickey und sendet ihn zurück an den Client.
    Der Client entschlüsselt das Passwort mit seinem Privatekey und hat das Passwort für die weitere Kommunikation.

    Lösung 2)
    Der Server generiert den Public- und Privatekey und schickt den Publickey unverschlüsselt an den Client.
    Der Client generiert mithilfe eines Passwortzufallsgenerator das Passwort für die symmetrische Verschlüsselung.
    Dieses Passwort verschlüsselt er mit dem Publickey und sendet ihn zurück an den Server.
    Der Server entschlüsselt das Passwort mit seinem Privatekey und hat das Passwort für die weitere Kommunikation.

    Ist es jetzt besser, wenn der Server für jeden einzelnen Client den Private- und Publickkey generiert oder der
    Client für sich selber.
    Ist es besser, wenn der Client das Passwort für die symmetrische Verschlüsselung generiert oder der Server für
    jeden einzelnen Client

    Im Endeffekt hat ja dann doch jeder alles (bis auf den Privatekey).
    Lösung 2)

    Ich denke das der Server mehr in Sicherheit ist, als der Client, und wenn ich den Client decompile komm ich ja an deine ganzen Keys und kann die Sache manipulieren. Läuft deine Serversoftware aber auf deinen Server und einer kommt an die Anwendung, kann auch keiner den Private Key lesen, das wäre auf jeden Fall sicherer.
    @ThuCommix: Erstmal danke für die Antwort

    Aber um noch schnell was richtig zu stellen:

    Im Code vom Client stehen ja nicht die ganzen Keys, sondern der Client erstellt, wenn er sich zum Server verbindet, die ganzen Keys (also Public- und Privatekey) neu und verwendet nicht immer die gleichen.
    Achso, ich dachte du verwendest immer den selben RSAKey. Aber wenn der Client beides generiert ist doch die Sicherheit nicht gewährleistet? - Da kann ich doch einfach jeden Key nehmen, wenn ich mich auf deinen Server verbinden will?
    Wenn man auf den Server verbinden will, braucht man ja kein Passwort.
    Es wird nur die weiter Kommunikation verschlüsselt, sodass keiner die Verbindung abhören kann.

    //EDIT
    Wenn ich jetzt die zweite Lösung verwende, dann generiert der Server für jeden Client, der sich auf den Server verbindet, einen Private- und Publickey.
    Der Publickey ist nur zum Verschlüsseln da und kann problemlos unverschlüsselt zum Client übertragen werden.
    Der Privatekey ist nur zum Entschlüsseln da, denn diesen verwendet dann der Server wieder zum entschlüsseln, nachdem der Client das Passwort für die symmetrische Verschlüsselung mit dem Publickey verschlüsselt hat.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „TheKing4241“ ()

    Ich seh jetzt erst einmal keinen allzu großen Unterschied ob das Schlüsselpaar vom Server oder vom Client generiert wird. Ich würde vermutlich selbst bevorzugen, es den Client machen zu lassen, und zwar allein, um damit den Server zu entlasten, der mit dem Austausch der Kommunikation zwischen den Clients schon genug zu tun hat - je nach Nutzung wohlgemerkt.
    Weltherrschaft erlangen: 1%
    Ist dein Problem erledigt? -> Dann markiere das Thema bitte entsprechend.
    Waren Beiträge dieser Diskussion dabei hilfreich? -> Dann klick dort jeweils auf den Hilfreich-Button.
    Danke.
    Warum soll der Server da groß ausgelastet sein?!
    Die Keys werden ja nur einmal beim Verbinden generiert, würd ich zumindest so machen.
    Die generierten Keys kannst du dann beim Server in die Klasse mit machen von der Verbindung.
    Vorausgesetzt man arbeitet mit Klassen. Ist auf jedenfall vorteilhaft.

    1. Client verbindet sich
    2. Server nimmt Verbindung an, generiert Key. Speichert es in der Klasse. Sendet zurück an den Client
    3. Client und Server haben beide den gleichen Key und können kommunizieren.

    Würde event noch nen Hauptkey benutzen, sodass die erste Verbindung schon verschlüsselt ist.
    So weiß der Server, aha jetzt kommt eine Verbindung von "meinen" Clienten und von niemand anders.
    Falls was anderes reinkommt, kann der Server die Verbindung trennen oder gar nicht annehmen.

    Kannst zb den MD5-Hash vom Client senden oder was weiß ich :)

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „n1nja“ ()

    n1nja schrieb:

    Warum soll der Server da groß ausgelastet sein?!

    Die Berechnung von Keys ist vielleicht(?) keine große Sache, aber ich habe bereits derartige Projekte gehabt und glaube mir, wann immer man eine Aufgabe in so einer Umgebung den Client erledigen lassen kann, sollte man das tun, schließlich kann man in vielen Fällen nicht immer davon ausgehen, dass nur eine angenomme Maximalmenge an Clients verbunden ist. Und die Aufgaben des Servers wachsen mit jedem Client der sich verbindet - mindestens linear, meist sogar exponentiell. Da können solche Kleinigkeiten schon den Unterschied ausmachen, der am Ende bedeutet, dass der Server nicht schon bei 1000 Clients in die Knie geht, sondern erst bei 1200 (um mal ein paar Zahlen aus der Luft zu greifen).
    Weltherrschaft erlangen: 1%
    Ist dein Problem erledigt? -> Dann markiere das Thema bitte entsprechend.
    Waren Beiträge dieser Diskussion dabei hilfreich? -> Dann klick dort jeweils auf den Hilfreich-Button.
    Danke.
    Wenn man es den Clienten überlässt ist die Möglich höher das man den generierten Key auch nachbilden kann?!
    Den irgendwo muss ja ein Algo sein, der das berechnet. Würde ich wenn es wirklich um Sicherheit geht nicht machen.
    Dann lies oben nochmal: Es geht darum, einen Key zu bauen, mit dem die nachfolgende(!) Kommunikation verschlüsselt wird. Die Verbindung zwischen Client und Server wird also "abhörsicher" gemacht, indem dynamisch ein Schlüsselpaar generiert wird auf das beide (Server und Client) sich verständigen. Wer das Paar generiert ist dabei tatsächlich Jacke wie Hose.* Ggf. kann man auch diesen Austausch bereits verschlüsseln, aber auch dafür müssen Client und Server über jeweils einen Teil eines Schlüsselpaars verfügen, der entweder "ausgehandelt" wird oder im Programm irgendwie fest verdrahtet ist. An einer Stelle muss man das Ei halt erfinden, damit daraus die Henne für das nächste Ei schlüpfen kann...

    *) In der Tat - wenn ich so drüber nachdenke - halte ich es sogar gar nicht mehr so unwichtig, wo das passiert, und denke, der Client ist besser geeignet. Denn wenn dieser seinen Public Key an den Server schickt, und jemand sollte den Schlüssel unterwegs abfangen, kann er sich damit nach wie vor nicht dem Server gegenüber als dieser Client ausgeben, denn dafür müsste er den Private Key des Clients haben. Ein kapernder Client kann als mit einem abgefangenen Schlüssel dennoch nicht verstehen was der Server ihm schickt (weil er es nicht entschlüsseln kann) und dem Server auch keine Nachrichten/Befehl im Namen des belauschten Clients senden.

    Anders herum könnte er sich aber dem kompromittierten Client gegenüber als Server ausgeben. Ob das - abgesehen von ggf. zu übermittelnden Login-Daten - aber gewinnbringend ist, wage ich zu bezweifeln, denn damit der Client davon nichts bemerkt, müsste der Angreifer ja im Grunde den Server und seine Kommunikation 1:1 nachbilden.

    n1nja schrieb:

    Den irgendwo muss ja ein Algo sein, der das berechnet.

    Okay, ich verstehe worauf du hinaus willst. Nimm einen Algo, der für die Berechnung Mausbewegungen/-Positionen und/oder andere variable Parameter wie gerade laufende Prozesse, belegter Speicherplatz, anzahl offene TCP/IP-Verbindungen etc. mit einbezieht, dann kann ein Angreifer selbst bei exakter Kenntnis des Algorithmus und des Systemtimers des Opfers den Schlüssel nicht nachbilden.
    Weltherrschaft erlangen: 1%
    Ist dein Problem erledigt? -> Dann markiere das Thema bitte entsprechend.
    Waren Beiträge dieser Diskussion dabei hilfreich? -> Dann klick dort jeweils auf den Hilfreich-Button.
    Danke.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Arby“ ()

    Warum soll der Server da groß ausgelastet sein?!

    Ich finde da hatt Arby schon recht, denn einen public- und privatekey mit einer Schlüssellänge von 2048 bit zu berechnen dauert schon an die drei sekunden (ja klar dass das nicht viel ist, aber bei größerer zahl der Verbindungen, kann das schon auslasten).
    Vor allem wenn man Schlüssellängen von 4096 bit verwendet, dann dauert dass schon an die 7-10 Sekunden und dass obwohl ich einen 8-kern Prozessor hab.

    n1nja schrieb:

    Wenn man es den Clienten überlässt ist die Möglich höher das man den generierten Key auch nachbilden kann?!
    Den irgendwo muss ja ein Algo sein, der das berechnet.

    Lies dir den Wikipedia eintrag dazu durch (de.m.wikipedia.org/wiki/RSA-Kryptosystem)
    Wenn man aus den publickey den privatekey berechnen will, na dann viel Spaß

    Und ja, ich Speicher den key in ner klasse für jeden client :D
    @Arby

    Ok das ist natürlich auch ne Möglichkeit:)
    Darauf bin ich selbst noch gar nicht gekommen, werde ich mir merken.
    Dann ist natürlich egal wo der Key generiert wird. Solang kein festern Algo besteht und es im Quelltext steht, braucht man sich "normal" keine Sorgen machen.
    Aber jeder weiß, die 100 prozentige Sicherheit wird es nie geben.

    @TheKing4241
    Wenn du deinen Key in der Klasse abspeicherst, kann man den trotzdem auslesen, sofern es sich nicht um eine native Datei handelt. Wobei man auch hier einfach was basteln kann um den Key
    von nativen Files auslesen kann.