Übertragungsprotokoll Auswahl



  • Hallo zusammen,

    und zwar lasse ich mir momentan Daten von einem Server schicken. Die Server- und Clientanwendung habe ich mit Boost.Asio gebastelt. Nun allerdings, möchte ich, dass die Daten verschlüsselt gesendet werden. Dazu möchte ich die AES Verschlüsselung (Rijndael / 256 Bit) nutzen. Als Lib dient mir Crypto++. Bei mir stellt sich nun allerdings eine Frage. Und zwar wäre es ja nun Blödsinn, den Key zum verschlüsseln sowie den Initialisierungsvector hardcoded in beide Anwendungen zu schreiben. Allerdings, müssen trotzdem beide Seiten Bescheid wissen zum entschlüsseln. Wie könnte man so etwas sinnvoll lösen? (Also nur in der Theorie, ich möchte keinen geschriebenen Code^^)


  • Mod

    Die generelle Idee ist, zunächst über public-key Methoden die Authentizität der Kommunikationspartner sicherzustellen und einen Sitzungsschlüssel auszuhandeln und den dann für eine (sehr viel effizientere) symmetrische Verschlüsselung wie AES zu benutzen.

    Das mag zwar einfach klingen, aber trotzdem - oder gerade deswegen - solltest du unbedingt vermeiden, das selber zu machen. Da gibt es viele mögliche Seitenkanalattacken, auf die du als Normalsterblicher nicht in einer Lebenszeit kommst. Schnapp dir stattdessen eine der großen und oft geprüften TLS-Bibliotheken.



  • Vielen Dank schonmal. War ja wieder klar, dass ich es mir zu einfach vorgestellt habe. Ist als Anfänger sehr schwer zu verstehen, wie so etwas immernoch angreifbar ist, wenn nur diese Chiffre geschickt wird^^. Aber gut, da muss man halt durch. Jetzt muss ich nur noch herausfinden wie ich in Boost.Asio TLS verwende und meinen bestehenden Code umschreiben muss^^.


  • Mod

    @zhavok sagte in Verschlüsselung Client/Server:

    Vielen Dank schonmal. War ja wieder klar, dass ich es mir zu einfach vorgestellt habe. Ist als Anfänger sehr schwer zu verstehen, wie so etwas immernoch angreifbar ist, wenn nur diese Chiffre geschickt wird^^. Aber gut, da muss man halt durch. Jetzt muss ich nur noch herausfinden wie ich in Boost.Asio TLS verwende und meinen bestehenden Code umschreiben muss^^.

    Die mathematische Theorie ist gar nicht mal soooo schwer. Kann man mit 1-2 Semestern Hochschulmathematik ganz gut verstehen, vielleicht auch schon als Oberstufenschüler, wenn man sich wirklich rein hängt. Das abgefahrene Zeug ist dann in der Praxis, wenn ein Angreifer irgendwelche Informationen über deine Zufallszahlen finden kann, indem er deine Antwortzeiten misst und dadurch Rückschlüsse zieht, welche Rechenoperationen dein Computer in dieser Zeit wohl durchgeführt haben könnte. Das ist halt all so Zeug, auf das man nie kommt. Daher mein Ratschlag, das nicht selber zu machen.



  • Kann man sagen, dass TSL das gleiche ist wie SSL? Denn zu Asio mit SSL finde ich einiges 🙂



  • @zhavok sagte in Verschlüsselung Client/Server:

    Kann man sagen, dass TSL das gleiche ist wie SSL?

    SSL vs. TLS - What's the Difference?



  • So wie ich es verstanden habe spricht man ab einer bestimmten SSL Version von TSL. Richtig?



  • Super. Vielen Dank für den Tipp mit TLS/SSL. Habe das jetzt mit Boost.Asio und openSSL realisiert und es funktioniert super. Nun ist bei mir noch eine Frage aufgekommen und ich hoffe ihr könnt mir dabei helfen.

    Und zwar geht es bei dem Projekt um eine App, welche sich nun mit meinem gebastelten Server verbinden soll. Die Frage ist wie ich das Protokoll von meinem Server gestalte. Der Server soll bei Anfragen Werte aus einer Datenbank lesen und schreiben. Außerdem soll es möglich sein Dateien hoch- und runter zu laden. Ich hatte überlegt ob ich dazu das HTTP Protokoll nachbaue. Ich würde dabei über Regex die Anfragen zerlegen und auswerten. Mit HTTP würde ich zumindest einen gewissen Standard nutzen.
    Auch überlegt hatte ich, ob ich mir mithilfe von JSON mein eigenes Protokoll bastel. Das wäre einfacher umzusetzen und ist dann genau auf meine Bedürfnisse und die des App Entwicklers abgestimmt.

    Welches Protokoll würde man in der Praxis nutzen? Bzw würde man ein eigenes schreiben?



  • Naja, REST oder REST-ähnliche Schnittstellen bieten sich an. HTTP und Json ist auf jeden Fall nicht verkehrt.
    Einen HTTP Server brauchst du nicht selber basteln, gibt eigentlich genügend fertige Implementierungen. z.B. proxygen von Facebook, kann man ganz einfach in eigene Anwendungen integrieren.



  • Die Idee mit JSON wäre für das eigene Protokoll gewesen. Könnte ja zum Beispiel so aussehen:

    //Client sendet
    { "method": "get", "type": "sql", "command": "checkAccData", "user": "Peter","pass": "1234" }
    
    //Server reagiert mit
    
    //unterscheide nach method
    //unterscheide nach type
    //Server sucht user in Datenbank und schaut welches Passwort er hat.
    //Server prüft ob Passwort gleich dem gesendetem Passwort ist. Wenn ja sende:
    {  "checkAccData": "true","errorcode": 0 }
    
    

    So hatte ich das gemeint. An dem Projekt arbeiten nur zwei Leute. Daher die Überlegung, ob es auf vielleicht einfacher ist das Protokoll selbst zu gestalten.
    Wenn du sagst HTTP wäre trotzdem besser, nehme ich das.



  • Was eigenes musst du selbst zusammen basteln. Http ist klar definiert und du kannst eine fertige Implementierung verwenden.



  • Genau. Ist zwar bissel mehr Schreibarbeit, aber somit auch ne Herausforderung. Und falls es irgendwo kracht, kenne ich meinen Code und finde schnell woran es liegt. Ich denke, dass dieser Weg noch einigermaßen akzeptabel ist und sich nicht gleich jeder Programmierer an den Kopf fasst.

    :smiling_face_with_open_mouth_cold_sweat:



  • @zhavok
    Ob Eigenentwicklung oder vorgefertigt: es ist immer die Frage was du erreichen willst und was deine Randbedingungen sind.
    Wenn du viel schnell von A nach B schaffen musst, sollte es natürlich ein Protokoll sein, was wenig Overhead hat, bzw. wo das Verhältnis zwischen Gesamtlänge einer Message und Inhalt der Message möglichst vorteilhaft ist. Wenn du aber nur dann und wann mal ne Message austauschst, ist die Performance mehr oder weniger egal und auch der Overhead ist vernachlässigbar.

    Wieviel Zeit kannst du dir nehmen?
    Glaubst du dass du mit einer Eigenentwicklung eines Protokolls deinen Horizont erweitern könntest?
    Transportierst du mehr Zahlen, oder mehr Strings?
    Wenn Zahlen, dann mehr ganzzahliges, oder Gleitkomma?

    Wenn du die ersten beiden Fragen mit "JA" beantwortest, solltest du dir selber was ausdenken, wenn nicht reicht auch eine vorgefertigte Lösung. 😉

    Ich für meinen Teil bastel mir gern eigene Dinge, wenns die Zeit erlaubt.



  • Ich würde es auch lieber selbst bauen. Wenn das Projekt jetzt fremde nutzen würde, dann greife ich natürlich lieber zu einem Standart. Aber da nur um mich und einen zweiten geht, denke ich reicht was eigenes. (Vorteil wäre nur noch, dass der Client gleich ne Lib wie cURL nutzen könnte). Bei beiden möglich muss ich dem Server erklären was genau er aus der Datenbank lesen soll bzw ob er anders reagieren soll. Beim Datentransfer hat natürlich HTTP schon alles fertig. Ich mache das bis jetzt immer so, dass ich dem Client die Größe der Datei schicke und dann in gleichmäßig großen Paketen schicke. Der Client wartet dabei bis die zuvor geschickte Größe erreicht wurde. Ich denke hier könnte man dann noch eine Prüfsumme mit ins Spiel bringen.

    Achso und ich habe alle Zeit der Welt. 😀



  • @zhavok sagte in Übertragungsprotokoll Auswahl:

    Achso und ich habe alle Zeit der Welt. 😀

    Das ist immer gut 😉

    Dein Dateipaket-Transfer-Prokoll klingt jetzt auch nicht nach viel Arbeit.

    • Initial die DateiGröße verschicken
    • warten auf Bestätigung durch Client ( "bin empfangsbereit" )
    • Paket verschicken
    • auf Bestätigung durch Client warten, nächsten Paket schicken
    • etc.
      Die Handshakevariante verhindert, dass du die Leitung überlastet.

    Ein Tag Arbeit würde ich sagen ( leicht handhabbares Socket-Framework vorausgesetzt ) 😉



  • Der Vorschlag ist gut. Bis jetzt hab ich mir das auch nur zusammen gereimt und dabei ist die Variante entstanden die ich geschrieben habe. Aber ich werde deine Idee ab jetzt für sowas anwenden 👍🏻



  • @zhavok sagte in Übertragungsprotokoll Auswahl:

    Ich denke, dass dieser Weg noch einigermaßen akzeptabel ist und sich nicht gleich jeder Programmierer an den Kopf fasst.

    An den Kopf fassen nicht, wir sind das schon gewohnt. NIH ist gerade bei Anfängern stark verbreitet.

    Wenn das ganze für Produktiv-Code ist, dann würde ich vorschlagen auf ein bestehendes Protokoll zurückzugreifen. Der Vorteil ist einfach dass du fertige Implementierungen wie z.B. libcurl hast. Die funktionieren. Eigenen Netzwerkcode schreiben ist was was man gerade als Anfänger eher vermeiden sollte, weil man da schnell Fehler einbauen kann. Die Socket Funktionen haben nämlich so einige Eigenheiten die zwar grundsätzlich alle irgendwo dokumentiert sind, die man aber als Anfänger schnell übersieht. Bzw. nicht weiss wo man die entsprechenden Infos suchen muss. Bzw. weil man falsche Annahmen trifft, und übersieht dass die Doku der Funktionen bestimmte Dinge von denen man ausgeht gar nicht garantiert. Dabei sind auch Fehler möglich die man später nicht mehr ohne Protokolländerung beheben kann. Was dann besonders lästig ist.

    Und als erfahrener Entwickler schreibt man (hoffentlich) auch nur dann Netzwerkcode wenn es wirklich nötig ist/wirklich viel bringen würde. Weil man (hoffentlich) irgendwann akzeptiert dass es keinen Sinn macht immer alles selbst zu schreiben.



  • @zhavok
    Wenn du tatsächlich nur Dateien verschicken willst, brauchst du auch nicht zu sehr auf den Overhead achten, da den Großteil des Datenaufkommens tatsächlich die eigentlichen Datei-Pakete darstellen werden. Bedenke aber, dass du hier wohl kein Token-Protokoll ( also z.B. kommasepariert ) nutzen kannst, da in dem eigentliche Datenpaket (binäre Datei), theoretisch jedes Steuerzeichen vorkommen kann, was dann theoretisch zu Fehlern beim Parsen führen kann.



  • @hustbaer sagte in Übertragungsprotokoll Auswahl:

    Eigenen Netzwerkcode schreiben ist was was man gerade als Anfänger eher vermeiden sollte, weil man da schnell Fehler einbauen kann.

    Das hängt davon ab wie sehr man noch Anfänger ist. Das Problem ist halt, dass viele gar nicht erkennen wann sie sich Socket-Programmierung zumuten können und daraus entstehen dann Programmierer ( ich sage bewusst nicht: Entwickler ), die eigentlich nur Interfaces von irgendwelchen Bibliotheken jonglieren können, aber noch nie ne Liste, ne Map oder ein Socketframework selber gebaut haben. Und das ist echt schade.

    Daher sage ich: Wer die Zeit hat, kann sich ruhig mal selber einarbeiten, auch in Sockets. Wenn es ein berufliches Projekt mit einem engen Zeitrahmen ist, sollte man natürlich existierende Bibliotheken nutzen, oder bereits vorliegenden firmeninternen Code ( wenn der taugt ).



  • Verzeiht mir falls ich jetzt die Begriffe durcheinander bringe, aber ich würde sagen Boost.Asio ist mein Socket Framework. Bin allgemein ein Freund der Boost Bibliothek 😄. Mit Asio hab ich jetzt seit ca 5 Monaten zu tun. Ich habe damit schon minimalistische Server gebaut die dazu dienen Dateien zu versenden und jeden Tag genutzt werden. Da war mein Protokoll noch wesentlich katastrophaler, aber es läuft bis heute. Ich würde definitiv nicht sagen, dass ich Ahnung von Socket - Programmierung habe, aber alles was ich bis jetzt damit gemacht habe, läuft wie es soll. Asio war zumindest bis jetzt immer gut zu mir ^^.


Log in to reply