Simpler TLS/SSL Client

  • Hallo zusammen,


    ich schaffe es einfach nicht einen einfachen TLS Client(TCP) zu bauen. Seit Wochen komme ich nicht weiter. Und zwar möchte ich einfach nur in einer App eine Verbindung zu einem Server aufbauen. Dann möchte ich dem Server eine Nachricht schicken und einfach das Echo davon erhalten. Also nichts kompliziertes. Ich selbst nutze Android Studio dafür und schreibe in Java. Der Server ist in C++ geschrieben und funktioniert auch (mit C++ Client getestet). Das Zertifikat habe ich als .pem vorliegen. Da ich nun schon so viele Wochen nicht weiter komme, suche ich jemandem der einfach mal via Teamviewer/AnyDesk mit Skype/Teamspeak etc. schaut was da schief läuft. Die Angelegenheit ist mir so wichtig, dass ich gern dazu bereit bin dafür zu zahlen. Schreibt mir eine PN oder einfach hier drunter. Ich hoffe mir kann jemand helfen und freue mich auf eure Antworten. :)

  • Funktioniert die Verbindung denn schon ohne SSL?
    Wenn ja, ist SSL korrekt auf dem C++ Server installiert?
    Welche Java-Klasse/Library benutzt du für deine Verbindung?


    Auf der Java/Client-Seite kannst du eigentlich die SSL-Socket Klasse benutzen und dann connecten.
    Eventuell (je nachdem wie das Zertifikat erstellt wurde) musst du das Zertifikat noch installieren (die .key datei, mit dem Private key) oder halt den TrustStore ignorieren.


    Ein paar mehr Infos oder Fehlermeldungen wären gut :)


    Ggfs. kann ich heute abend per Teamviewer/TS helfen.

  • hallo auch interessant ist was ist für ein Zertifikat? Ich meine ein eibenzertzfizirtes oder von einer offiziellen Stelle zertifiziertes und eingetragenes Zertifikat ?
    Beim zweiten sollte es mit dem installieren klappen.
    Kannst du vom Browser auf den Server zugreifen.


    Im Punkt wenig Infos muss ich meinem vorredner recht geben.


    Was für eine Verbindung willst du aufbauen https denke ich .
    Benutzt du Android Bord mittel oder eine lib?
    Wie und wo hast du versucht das Zertifikat in deinen Code einzubauen?

  • Nein, die Verbindung funktioniert nicht ohne SSL. Der C++ Server funktioniert nur mit SSL. Das Zertifikat ist nicht offiziell zertifiziert. Ich versuche auch nicht per HTTP/HTTPS darauf zuzugreifen. Es gibt kein direktes Protokoll (außer halt IPv4 und TCP^^). Ich möchte nur eine Nachricht hinschicken und auch genau so zurück bekommen. Den C++ Code schreib ich gleich mal hier rein:



    Ich muss leider erstmal los. Melde mich heute Abend wieder :)

  • Hallo habe mir deinen Code jetzt nicht angesehen vielleicht später.


    Aber woher weist du das dein Server Fehlerfrei läuft?
    Im Internet benutz man eigentlich immer ein auf TCP basierendes Protokoll.
    Zb. http oder https


    Wie mit welchen Methoden willst dudenn vom Handy aus auf deinen Server zugreifen?

  • Weil ich in C++ einen SSL Client geschrieben habe, der genau dieses simple Verfahren macht. Nur bekomm ich es auf Android nicht hin^^. Hier der Client Code (Server und Client basieren übrigens auf dem Beispiel den Beispielen von Boost (https://www.boost.org/doc/libs…mple/cpp03/ssl/client.cpp https://www.boost.org/doc/libs…mple/cpp03/ssl/server.cpp)



    Ich benutze auch das TCP Protokoll. (Steht auch in Zeile 23 vom Server und Zeile 122 im Client beim Resolver). Aber HTTP benutze ich nicht. Brauch ich auch nicht. Ich baue keinen Webserver.
    Mal ein ausgedachtes Szenario, wo so etwas Anwendung finden kann:



    Sagen wir mal ich möchte von meinem Smartphone ein Command zu meinem Rechner schicken. Zum Beispiel, dass er sich ausschalten soll. Dann schick ich einfach ein TCP Packet mit dem Inhalt "shutdown". Das ganze schicke ich übers WLAN an die lokale IP meines Rechners. Auf dem Rechner läuft der C++ Server. Der nimmt das Packet und liest "shutdown". Eine Abfrage innerhalb des Servers lautet jetzt "Wenn shutdown gesendet wird, dann fahre dich herunter".
    Allerdings nutzt auch mein Nachbar mein WLAN. Er könnte nun über eine "Man in the Middle" Attacke meinen Datenverkehr mitschneiden. Er sieht auch auch mein Shutdown Packet. Das geht ihn aber nichts an. Dafür verschlüssle ich die Daten zwischen Rechner(wo der Server drauf läuft) und Smartphone (wo der Client drauf läuft). SSL bietet eine Verschlüsselung zwischen Client und Server mit Schlüsselaustausch usw.. Also genau das richtige. Habe mich auch Schlau gemacht, in genau solchen Fällen greift man auch zu SSL. Ein offizielles Zertifikat brauche ich dafür nicht. Ich habe keinen Browser, der abgleicht ob der PublicKey jetzt ok ist oder nicht. Meine Schlüssel dienen ja nur mir und dem Projekt.


    Für diesen einfachen Fall brauch ich ja nun nicht stundenlang das HTTP Protokoll implementieren und mich damit auseinander setzen. Der Rechner reagiert nur auf den simplen Text "shutdown".


    Das war jetzt mal ein sehr gesponnenes Szenario. Aber Fakt ist, dass auch auf Android eine SSL Verbindung auf eigene Protokolle reagieren muss. Denn SSL an sich setzt kein Protokoll vorraus. Ich hoffe ihr könnt euch jetzt etwas mehr darunter vorstellen^^.

  • Dazu musszest du auch eine Socket Verbindung unter Android aufbauen und natürlich den Text auch selber mit ssl verschlüsseln und den verschlüsselten string über das Socket senden.


    Aber was machst du wenn dein Nachbar das TCP packet mit snifft und denn darin enthaltenen Text nimmt und selber nach dem er eine Verbindung aufgebaut hat den selben Text sendet dann schaltet sich dein Rechner wahrscheinlich auch aus.

  • Er könnte natürlich das Packet mitschneiden. Aber es ist eben verschlüsselt. Sicher kann er das verschlüsselte Packet zu meinem Rechner senden und der reagiert dann auch darauf, aber von Grund auf weiß er ja garnicht erst was drin steht, weils eben verschlüsselt ist. Er weiß also auch nicht, dass da shutdown drin steht. Aber das mit dem Nachbar war auch nur ein Beispiel. Es sollen später mal sensible Daten über ein eigenes Protokoll gesendet werden. Diese sollte man aber eben nicht mal einfach mitsniffen und dann in Ruhe durchlesen können. Zwar kann man die Daten mitschneiden, aber bekommt den Inhalt nicht heraus. Nach dem Schlüsselaustausch verwendet TLS ja eine synchrone Verschlüsselung. Ich glaube AES müsste es sein. Er hat also lediglich nen ganzen Haufen verschlüsselte Packete, die ihm nichts bringen.

  • Genau da das Zertifikat nicht aus einer offizellen CA kommt, musst du es installieren bzw den TrustStore ausschalten/ignorieren.
    Die Verbindung solltest du via der SSLSocket-Klasse hinbekommen.


    @jogimuc den Text muss man nicht extra nochmal selber verschlüsseln, das übernimmt der SSLSocket mit hilfe des Zertifkates und des Handshakes.
    Sobald der Nachbar selber eine Verbindung aufbaut, muss er auch einen Handshake machen und kann somit das alte(gesniffte) Paket nicht mehr nutzen.


    Wie Mindfreak, das schon vor hat ist es richtig.
    C++ kann ich leider nicht, da gehe ich jetzt einfach mal von aus, das alles passt.


    Mein Vorschlag für solche Projekte wäre übrigens den Server in Java mit der Jetty-Library zu schreiben. Dann hast du einen kleine Http-Server und kannst mithilfe von Servlets deinen Code schreiben. Dann kannst du den Server mit SSL ausstatten und ganz einfach via HTTP-Client Librarys (z.B. Okhttp) deine Requests machen.


    Wie gesagt sollte es mit der SSLSocket-Klasse eigentlich kein Problem sein.
    Falls du da noch Fehler oder Hilfe brauchst, kannst dich ja melden :)

  • Abend,


    ich hau mal ein Java Code rein damit es vielleicht die ein oder andere Frage klärt.




    was ich bisher erfahren habe, ist das die diese Methode veraltet ist. Laut aussagen muss man in AsyncTask die ganze Sache schreiben.



    Code
    E/AndroidRuntime: FATAL EXCEPTION: main
                  Process: com.example.xxxxx.xxx, PID: 2387
                  android.os.NetworkOnMainThreadException


    Mein Fehlercode.


    Ich würde es gerne mal versuchen mit dem AsyncTask. Hab es aber noch nicht hinbekommen. Ich weiß nicht wie ich das mit AsyncTask schreiben muss.

  • Die android.os.NetworkOnMainThreadException sagt aus, dass du versuchst auf den Main-Thread Netzwerk Operationen auszuführen, was nicht erlaubt ist.
    Startet einfach die Netzwerk-Operationen in einen neuen Thread.
    So in etwa sollte es gehen, aber kann es aber gerade nicht testen, eventuell musst du da noch paar Sachen anpassen.

  • So folgendes ist passiert,


    hab das von dir übernommen und den Syntax nur ausgebessert.


    Ich drücke Senden, App stürzt ab folgende Fehlermeldung kommt.


    Code
    10-08 17:15:23.822 1814-1841/com.example.xxxxxx.xxx E/AndroidRuntime: FATAL EXCEPTION: Thread-4
        Process: com.example.xxxxxxx.xxx, PID: 1814
        android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.


    Trotzdem war es schon mal ein erfolg.


    Es kam etwas beim Server an und zwar folgendes.
    Anbei ich habe als Nachricht "test" geschrieben



  • Ich schlüssle das obige mal auf:
    Also erst kommt die eigentliche Nachricht in Zeile 1.
    Ab Zeile 2 kommt der Rest unseres Diffie-Hellman Schlüssels.



    Code
    -----BEGIN DH PARAMETERS-----
    MIIBCAKCAQEAsbliBfUhTnrGVwBQGT7fVpNX8rqP0XgEsN79wslNxFZr4cC5rZ0k
    IgP8QnFW1l0C7J1HzDqjcPsyuXAKgcu4nMe6G81s0jQlt2xoBKzbOiGwPNx3ehMs
    h+NqOSWkJo1j87IPXLtbyyLtIPYeLtFQ1ihkGulvsxLQAwbFkqu29oC6l+1Nffvr
    tJIoVt9p0jtEk+qih+gUG/yXpeWlXFeAZbuYtgyMs/NowZx3LdziLf8hE5sYnBUp
    mseYBxu9SWe3fy35pM3zN6pG5GkZyoHgtAl2odNHeKtV4fesyQeBwRFv98ZnBFvN
    7mANau2qBh4lPNksKrDMlsJAQnwzGORXIwIBAg==
    -----END DH PARAMETERS-----

    (Siehe hier ab Zeile 7)



    Dann Zeile 4 kommt S-----, also nochmal das Ende des Diffie-Hellman Schlüssels.
    Ab Zeile 5 stammt das folgende aus unserem Private Key bis Zeile 19 Zeichen 31, also der "5".



    (Siehe Hier von Zeile 8 Zeichen 4 bis Zeile 22 Zeichen 31)



    Der Rest (;ñvT4k) ist mir unbekannt. Wahrscheinlich stimmt da was beim Encoding nicht^^.
    Das ist übrigens eh nur ein Testzertifikat. Deshalb teile ich meine Keys^^

  • Im Thread wird noch auf v zugegriffen. Das darf dann natürlich nicht mehr bzw. man muss den Teil auslagern. Da habe ich auf der schnelle nicht drauf geachtet.
    Dann sollte das auch passen :)
    Bei dem Input- und OutputStreamReader kannst du noch ein Charset angeben (z.B UTF-8)https://docs.oracle.com/javase…io/InputStreamReader.html
    Dann musst du Server-seitig das Encoding natürlich auch auf UTF-8 stellen.
    Bei den Rest kann ich dir leider nicht großartig,da ich kein C++ kann :/

  • Vielen Dank. Ich kann das leider erst morgen Abend testen, weil ich bis dahin nicht zu Hause bin. Das der Server die Zertifikate mit ausgibt scheint ein Fehler bei meinem C++ Code gewesen zu sein. Ich habe den kompletten Puffer ausgegeben anstatt nur die angekommenen Bytes. Ich melde mich also morgen Abend nochmal.

  • Hallo das v ist eine View und die beinhaltet nicht deine Resourcen.



    InputStream keyin = v.getResources().openRawResource(R.raw.neuserverkeypem);


    etweder
    InputStream keyin = this.getResources().openRawResource(R.raw.neuserverkeypem);
    oder
    InputStream keyin = getampplicationcontext().getResources().openRawResource(R.raw.neuserverkeypem);
    müsstes es denke ich heissen den du bist ja imThread.
    ansonsten mus das v natürlich bleiben.


    Ps. das ist auch falsch
    der erste Parameter muss auch der context sein


    Toast.makeText(getampplicationcontext(), "Bitte IP und Port eingeben", Toast.LENGTH_LONG).show();

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!