Simpler TLS/SSL Client

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • 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?
    Ein Feedback auf Tipps ist auch schön. :P
  • 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:

    C-Quellcode

    1. #include <iostream>
    2. #include <string>
    3. #include <array>
    4. #include <boost/bind.hpp>
    5. #include <boost/asio.hpp>
    6. #include <boost/asio/ssl.hpp>
    7. typedef boost::asio::ssl::stream<boost::asio::ip::tcp::socket> ssl_socket;
    8. std::string pass() {
    9. return "test";
    10. }
    11. int main() {
    12. std::cout << "Server started..." << std::endl;
    13. while (true) {
    14. try {
    15. //Start TLS Socket
    16. boost::asio::io_context io_context;
    17. boost::asio::ip::tcp::acceptor acceptor(io_context, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), 11880));
    18. boost::asio::ssl::context context(boost::asio::ssl::context::sslv23);
    19. context.set_options(
    20. boost::asio::ssl::context::default_workarounds
    21. | boost::asio::ssl::context::no_sslv2);
    22. context.use_certificate_chain_file("public.pem");
    23. context.set_password_callback(boost::bind(pass));
    24. context.use_private_key_file("private.pem", boost::asio::ssl::context::pem);
    25. context.use_tmp_dh_file("dh2048.pem");
    26. ssl_socket stream(io_context, context);
    27. boost::asio::ip::tcp::endpoint peer_endpoint;
    28. acceptor.accept(stream.lowest_layer(), peer_endpoint);
    29. boost::system::error_code ec;
    30. stream.handshake(boost::asio::ssl::stream_base::server, ec);
    31. std::string response;
    32. std::string incoming;
    33. std::array<char, 1024> buffer;
    34. buffer.fill(0);
    35. boost::system::error_code error;
    36. stream.read_some(boost::asio::buffer(buffer, sizeof(buffer)), error); //Nachricht kommt an
    37. incoming = buffer.data();
    38. std::cout << incoming << std::endl;
    39. response += "ist angekommen: (" + incoming + ")"; //Antwort = "ist angekommen (%meineNachricht%)"
    40. boost::asio::write(stream, boost::asio::buffer(response, response.length())); //Antwort senden
    41. }
    42. catch (std::exception& myexc) {
    43. std::cout << myexc.what() << std::endl;
    44. }
    45. }
    46. }
    Alles anzeigen

    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?
    Ein Feedback auf Tipps ist auch schön. :P
  • 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 (boost.org/doc/libs/1_68_0/doc/…mple/cpp03/ssl/client.cpp boost.org/doc/libs/1_68_0/doc/…mple/cpp03/ssl/server.cpp)

    C-Quellcode

    1. #include <cstdlib>
    2. #include <iostream>
    3. #include <boost/bind.hpp>
    4. #include <boost/asio.hpp>
    5. #include <boost/asio/ssl.hpp>
    6. #include <string>
    7. enum { max_length = 1024 };
    8. class client
    9. {
    10. public:
    11. client(boost::asio::io_context& io_context,
    12. boost::asio::ssl::context& context,
    13. boost::asio::ip::tcp::resolver::results_type endpoints)
    14. : socket_(io_context, context)
    15. {
    16. socket_.set_verify_mode(boost::asio::ssl::verify_peer);
    17. socket_.set_verify_callback(
    18. boost::bind(&client::verify_certificate, this, _1, _2));
    19. boost::asio::async_connect(socket_.lowest_layer(), endpoints,
    20. boost::bind(&client::handle_connect, this,
    21. boost::asio::placeholders::error));
    22. }
    23. bool verify_certificate(bool preverified,
    24. boost::asio::ssl::verify_context& ctx)
    25. {
    26. char subject_name[256];
    27. X509* cert = X509_STORE_CTX_get_current_cert(ctx.native_handle());
    28. X509_NAME_oneline(X509_get_subject_name(cert), subject_name, 256);
    29. return preverified;
    30. }
    31. void handle_connect(const boost::system::error_code& error)
    32. {
    33. if (!error)
    34. {
    35. socket_.async_handshake(boost::asio::ssl::stream_base::client,
    36. boost::bind(&client::handle_handshake, this,
    37. boost::asio::placeholders::error));
    38. }
    39. else
    40. {
    41. std::cout << "Connect failed: " << error.message() << "\n";
    42. }
    43. }
    44. void handle_handshake(const boost::system::error_code& error)
    45. {
    46. if (!error)
    47. {
    48. std::cout << "Enter message: ";
    49. std::cin.getline(request_, max_length);
    50. size_t request_length = strlen(request_);
    51. boost::asio::async_write(socket_,
    52. boost::asio::buffer(request_),
    53. boost::bind(&client::handle_write, this,
    54. boost::asio::placeholders::error,
    55. boost::asio::placeholders::bytes_transferred));
    56. }
    57. else
    58. {
    59. std::cout << "Handshake failed: " << error.message() << "\n";
    60. }
    61. }
    62. void handle_write(const boost::system::error_code& error,
    63. size_t bytes_transferred)
    64. {
    65. if (!error)
    66. {
    67. reply_.fill(0);
    68. socket_.async_read_some(boost::asio::buffer(reply_, 1024),
    69. boost::bind(&client::handle_read, this,
    70. boost::asio::placeholders::error,
    71. boost::asio::placeholders::bytes_transferred));
    72. }
    73. else
    74. {
    75. std::cout << "Write failed: " << error.message() << "\n";
    76. }
    77. }
    78. void handle_read(const boost::system::error_code& error,
    79. size_t bytes_transferred)
    80. {
    81. if (!error)
    82. {
    83. size_t length = bytes_transferred;
    84. std::string test;
    85. for (UINT i = 0; i < length; i++) {
    86. test += reply_[i];
    87. }
    88. std::cout << test;
    89. std::cout << "\n";
    90. }
    91. else
    92. {
    93. std::cout << "Read failed: " << error.message() << "\n";
    94. }
    95. }
    96. private:
    97. boost::asio::ssl::stream<boost::asio::ip::tcp::socket> socket_;
    98. char request_[max_length];
    99. std::array<char, 1024> reply_;
    100. };
    101. int main() {
    102. try {
    103. while (true) {
    104. boost::asio::io_context io_context;
    105. boost::asio::ip::tcp::resolver resolver(io_context);
    106. boost::asio::ip::tcp::resolver::results_type endpoints = resolver.resolve("127.0.0.1", "11880");
    107. boost::asio::ssl::context ctx(boost::asio::ssl::context::sslv23);
    108. ctx.load_verify_file("public.pem");
    109. client c(io_context, ctx, endpoints);
    110. io_context.run();
    111. std::cin.get();
    112. }
    113. }
    114. catch (std::exception& myexc) {
    115. std::cerr << "Exception: " << myexc.what() << "\n";
    116. std::cin.get();
    117. }
    118. return 0;
    119. }
    Alles anzeigen

    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^^.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Mindfreak ()

  • 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.
    Ein Feedback auf Tipps ist auch schön. :P
  • 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.


    Quellcode

    1. public class MainActivity extends Activity {
    2. // Inistailierung
    3. Button Send;
    4. EditText IP;
    5. EditText Port;
    6. TextView Answer;
    7. EditText Message;
    8. private String ip_address;
    9. private int port = 11880;
    10. private SSLSocket socket = null;
    11. private BufferedReader in = null;
    12. private BufferedWriter out = null;
    13. private final String TAG = "TAG";
    14. private char keystorepass[] = "key12345".toCharArray();
    15. @Override
    16. protected void onCreate(Bundle savedInstanceState) {
    17. super.onCreate(savedInstanceState);
    18. setContentView(R.layout.activity_main);
    19. Send = (Button) findViewById(R.id.btnSend);
    20. IP = (EditText) findViewById(R.id.etIP);
    21. Port = (EditText) findViewById(R.id.etPort);
    22. Answer = (TextView) findViewById(R.id.tvAnswer);
    23. Message = (EditText) findViewById(R.id.etMessage);
    24. Send.setClickable(true);
    25. Send.setOnClickListener(new View.OnClickListener() {
    26. @Override
    27. public void onClick(View v) {
    28. if (IP.getText().toString().equals(null) || Port.getText().toString().equals(null)){
    29. Toast.makeText(v.getContext(), "Bitte IP und Port eingeben", Toast.LENGTH_LONG).show();
    30. }else {
    31. String temp = Message.getText().toString();
    32. if (temp == null){
    33. temp = "Es wurde keine Nachricht eingegeben";
    34. }
    35. port = Integer.parseInt(Port.getText().toString());
    36. ip_address = IP.getText().toString();
    37. try {
    38. KeyStore ks = KeyStore.getInstance("BKS");
    39. InputStream keyin = v.getResources().openRawResource(R.raw.neuserverkeypem);
    40. ks.load(keyin,keystorepass);
    41. org.apache.http.conn.ssl.SSLSocketFactory socketFactory = new org.apache.http.conn.ssl.SSLSocketFactory(ks);
    42. socketFactory.setHostnameVerifier(socketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
    43. socket = (SSLSocket)
    44. socketFactory.createSocket(new Socket(ip_address,port), ip_address, port, false);
    45. socket.startHandshake();
    46. printServerCertificate(socket);
    47. printSocketInfo(socket);
    48. out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
    49. in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    50. chat(temp);
    51. } catch (UnknownHostException e) {
    52. Toast.makeText(v.getContext(), "Unknown host", Toast.LENGTH_SHORT).show();
    53. Log.i(TAG,"Unknown host");
    54. //System.exit(1);
    55. } catch (IOException e) {
    56. Toast.makeText(v.getContext(), "No I/O", Toast.LENGTH_SHORT).show();
    57. Log.i(TAG,"No I/O");
    58. e.printStackTrace();
    59. //System.exit(1);
    60. } catch (KeyStoreException e) {
    61. Toast.makeText(v.getContext(), "Keystore ks error", Toast.LENGTH_SHORT).show();
    62. Log.i(TAG,"Keystore ks error");
    63. //System.exit(-1);
    64. } catch (NoSuchAlgorithmException e) {
    65. Toast.makeText(v.getContext(), "No such algorithm for ks.load", Toast.LENGTH_SHORT).show();
    66. Log.i(TAG,"No such algorithm for ks.load");
    67. e.printStackTrace();
    68. //System.exit(-1);
    69. } catch (CertificateException e) {
    70. Toast.makeText(v.getContext(), "certificate missing", Toast.LENGTH_SHORT).show();
    71. Log.i(TAG,"certificate missing");
    72. e.printStackTrace();
    73. //System.exit(-1);
    74. } catch (UnrecoverableKeyException e) {
    75. Toast.makeText(v.getContext(), "UnrecoverableKeyException", Toast.LENGTH_SHORT).show();
    76. Log.i(TAG,"unrecoverableKeyException");
    77. e.printStackTrace();
    78. //System.exit(-1);
    79. } catch (KeyManagementException e) {
    80. Toast.makeText(v.getContext(), "KeyManagementException", Toast.LENGTH_SHORT).show();
    81. Log.i(TAG,"key management exception");
    82. e.printStackTrace();
    83. //System.exit(-1);
    84. }
    85. }
    86. }
    87. });
    88. }
    89. private void printServerCertificate(SSLSocket socket) {
    90. try {
    91. Certificate[] serverCerts =
    92. socket.getSession().getPeerCertificates();
    93. for (int i = 0; i < serverCerts.length; i++) {
    94. Certificate myCert = serverCerts[i];
    95. Log.i(TAG,"====Certificate:" + (i+1) + "====");
    96. Log.i(TAG,"-Public Key-\n" + myCert.getPublicKey());
    97. Log.i(TAG,"-Certificate Type-\n " + myCert.getType());
    98. System.out.println();
    99. }
    100. } catch (SSLPeerUnverifiedException e) {
    101. Log.i(TAG,"Could not verify peer");
    102. e.printStackTrace();
    103. System.exit(-1);
    104. }
    105. }
    106. private void printSocketInfo(SSLSocket s) {
    107. Log.i(TAG,"Socket class: "+s.getClass());
    108. Log.i(TAG," Remote address = "
    109. +s.getInetAddress().toString());
    110. Log.i(TAG," Remote port = "+s.getPort());
    111. Log.i(TAG," Local socket address = "
    112. +s.getLocalSocketAddress().toString());
    113. Log.i(TAG," Local address = "
    114. +s.getLocalAddress().toString());
    115. Log.i(TAG," Local port = "+s.getLocalPort());
    116. Log.i(TAG," Need client authentication = "
    117. +s.getNeedClientAuth());
    118. SSLSession ss = s.getSession();
    119. Log.i(TAG," Cipher suite = "+ss.getCipherSuite());
    120. Log.i(TAG," Protocol = "+ss.getProtocol());
    121. }
    122. public void chat(String temp){
    123. String message = temp;
    124. String line = "";
    125. // send id of the device to match with the image
    126. try {
    127. out.write(message+"\n");
    128. out.flush();
    129. } catch (IOException e2) {
    130. Log.i(TAG,"Read failed");
    131. System.exit(1);
    132. }
    133. // receive a ready command from the server
    134. try {
    135. line = in.readLine();
    136. Answer.setText("SERVER SAID: "+line);
    137. //Log.i(TAG,line);
    138. } catch (IOException e1) {
    139. Log.i(TAG,"Read failed");
    140. System.exit(1);
    141. }
    142. }
    143. }
    Alles anzeigen

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


    Quellcode

    1. E/AndroidRuntime: FATAL EXCEPTION: main
    2. Process: com.example.xxxxx.xxx, PID: 2387
    3. 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.

    Java-Quellcode

    1. public class MainActivity extends Activity {
    2. // Inistailierung
    3. Button Send;
    4. EditText IP;
    5. EditText Port;
    6. TextView Answer;
    7. EditText Message;
    8. private String ip_address;
    9. private int port = 11880;
    10. private SSLSocket socket = null;
    11. private BufferedReader in = null;
    12. private BufferedWriter out = null;
    13. private final String TAG = "TAG";
    14. private char keystorepass[] = "key12345".toCharArray();
    15. @Override
    16. protected void onCreate(Bundle savedInstanceState) {
    17. super.onCreate(savedInstanceState);
    18. setContentView(R.layout.activity_main);
    19. Send = (Button) findViewById(R.id.btnSend);
    20. IP = (EditText) findViewById(R.id.etIP);
    21. Port = (EditText) findViewById(R.id.etPort);
    22. Answer = (TextView) findViewById(R.id.tvAnswer);
    23. Message = (EditText) findViewById(R.id.etMessage);
    24. Send.setClickable(true);
    25. Send.setOnClickListener(new View.OnClickListener() {
    26. @Override
    27. public void onClick(View v) {
    28. if (IP.getText().toString().equals(null) || Port.getText().toString().equals(null)){
    29. Toast.makeText(v.getContext(), "Bitte IP und Port eingeben", Toast.LENGTH_LONG).show();
    30. }else {
    31. String temp = Message.getText().toString();
    32. if (temp == null){
    33. temp = "Es wurde keine Nachricht eingegeben";
    34. }
    35. port = Integer.parseInt(Port.getText().toString());
    36. ip_address = IP.getText().toString();
    37. try{
    38. //HIER DEN NETZWERK-OPERATIONEN IN NEUEN THREAD STARTEN
    39. new Thread() {
    40. @Override
    41. public void run() {
    42. try {
    43. KeyStore ks = KeyStore.getInstance("BKS");
    44. InputStream keyin = v.getResources().openRawResource(R.raw.neuserverkeypem);
    45. ks.load(keyin,keystorepass);
    46. org.apache.http.conn.ssl.SSLSocketFactory socketFactory = new org.apache.http.conn.ssl.SSLSocketFactory(ks);
    47. socketFactory.setHostnameVerifier(socketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
    48. socket = (SSLSocket)
    49. socketFactory.createSocket(new Socket(ip_address,port), ip_address, port, false);
    50. socket.startHandshake();
    51. printServerCertificate(socket);
    52. printSocketInfo(socket);
    53. out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
    54. in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    55. chat(temp);
    56. } catch (UnknownHostException e) {
    57. Toast.makeText(v.getContext(), "Unknown host", Toast.LENGTH_SHORT).show();
    58. Log.i(TAG,"Unknown host");
    59. //System.exit(1);
    60. } catch (IOException e) {
    61. Toast.makeText(v.getContext(), "No I/O", Toast.LENGTH_SHORT).show();
    62. Log.i(TAG,"No I/O");
    63. e.printStackTrace();
    64. //System.exit(1);
    65. } catch (KeyStoreException e) {
    66. Toast.makeText(v.getContext(), "Keystore ks error", Toast.LENGTH_SHORT).show();
    67. Log.i(TAG,"Keystore ks error");
    68. //System.exit(-1);
    69. } catch (NoSuchAlgorithmException e) {
    70. Toast.makeText(v.getContext(), "No such algorithm for ks.load", Toast.LENGTH_SHORT).show();
    71. Log.i(TAG,"No such algorithm for ks.load");
    72. e.printStackTrace();
    73. //System.exit(-1);
    74. } catch (CertificateException e) {
    75. Toast.makeText(v.getContext(), "certificate missing", Toast.LENGTH_SHORT).show();
    76. Log.i(TAG,"certificate missing");
    77. e.printStackTrace();
    78. //System.exit(-1);
    79. } catch (UnrecoverableKeyException e) {
    80. Toast.makeText(v.getContext(), "UnrecoverableKeyException", Toast.LENGTH_SHORT).show();
    81. Log.i(TAG,"unrecoverableKeyException");
    82. e.printStackTrace();
    83. //System.exit(-1);
    84. } catch (KeyManagementException e) {
    85. Toast.makeText(v.getContext(), "KeyManagementException", Toast.LENGTH_SHORT).show();
    86. Log.i(TAG,"key management exception");
    87. e.printStackTrace();
    88. //System.exit(-1);
    89. }
    90. }
    91. }).start();
    92. }
    93. catch(Exception ex){}
    94. }
    95. }
    96. });
    97. }
    98. private void printServerCertificate(SSLSocket socket) {
    99. try {
    100. Certificate[] serverCerts =
    101. socket.getSession().getPeerCertificates();
    102. for (int i = 0; i < serverCerts.length; i++) {
    103. Certificate myCert = serverCerts[i];
    104. Log.i(TAG,"====Certificate:" + (i+1) + "====");
    105. Log.i(TAG,"-Public Key-\n" + myCert.getPublicKey());
    106. Log.i(TAG,"-Certificate Type-\n " + myCert.getType());
    107. System.out.println();
    108. }
    109. } catch (SSLPeerUnverifiedException e) {
    110. Log.i(TAG,"Could not verify peer");
    111. e.printStackTrace();
    112. System.exit(-1);
    113. }
    114. }
    115. private void printSocketInfo(SSLSocket s) {
    116. Log.i(TAG,"Socket class: "+s.getClass());
    117. Log.i(TAG," Remote address = "
    118. +s.getInetAddress().toString());
    119. Log.i(TAG," Remote port = "+s.getPort());
    120. Log.i(TAG," Local socket address = "
    121. +s.getLocalSocketAddress().toString());
    122. Log.i(TAG," Local address = "
    123. +s.getLocalAddress().toString());
    124. Log.i(TAG," Local port = "+s.getLocalPort());
    125. Log.i(TAG," Need client authentication = "
    126. +s.getNeedClientAuth());
    127. SSLSession ss = s.getSession();
    128. Log.i(TAG," Cipher suite = "+ss.getCipherSuite());
    129. Log.i(TAG," Protocol = "+ss.getProtocol());
    130. }
    131. public void chat(String temp){
    132. String message = temp;
    133. String line = "";
    134. // send id of the device to match with the image
    135. try {
    136. out.write(message+"\n");
    137. out.flush();
    138. } catch (IOException e2) {
    139. Log.i(TAG,"Read failed");
    140. System.exit(1);
    141. }
    142. // receive a ready command from the server
    143. try {
    144. line = in.readLine();
    145. Answer.setText("SERVER SAID: "+line);
    146. //Log.i(TAG,line);
    147. } catch (IOException e1) {
    148. Log.i(TAG,"Read failed");
    149. System.exit(1);
    150. }
    151. }
    152. }
    Alles anzeigen
  • 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.

    Quellcode

    1. 10-08 17:15:23.822 1814-1841/com.example.xxxxxx.xxx E/AndroidRuntime: FATAL EXCEPTION: Thread-4
    2. Process: com.example.xxxxxxx.xxx, PID: 1814
    3. 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


    Quellcode

    1. test
    2. ANau2qBh4lPNksKrDMlsJAQnwzGORXIwIBAg==
    3. -----END DH PARAMETERS-----
    4. S-----
    5. lGJYbY7IuK9+MQWTFx8Eg5s1JU5dE/Xw0EetVSAxYNP+r56pHwmxZEXB/aAmF
    6. OYeZqrwnHzfEZHpQ9khf86sp42aNryrzYqpbnaUknM2DPQAFxxekX4QCLVXMEB8o
    7. x6gpxTBupu8xQhhE901MRh7XLvyAwLJ8qpYbF2dpimb2/EoUsjb/let6W55pA5bJ
    8. Y9nzCaX5NPU8fHjgvHzaa9dCbUv9lAhQJLQtBkSyPB5fuw1tMY7VmVsxNURunNjV
    9. eREJ/r2fQuuPEEkrtRfzmFDwL+w8D505jV5ofxdN4qC+74YAecel6Vlb4uOMtIcv
    10. MUlZ3kECgYEA2hLjMXOa74dMyZ0qrhFpTs4tg9mwkVuQ254FmHOyMx2BTd9Z09/+
    11. nYZJjbOl61I3m/7eChNv/FLjId6R2EoYcDJ3SrCxEZoemDb/uyC3QpWKZG9yN/vh
    12. JmDcayyHClrOmFxFSD0SQeaqAbiQeScly7nmYKpJysVr9NmErdG7ieUCgYEA1NCN
    13. WHfVEZNu6LN3jELSj5FXTqdMo5fr+QSAdinc0pnzIG4kHa6pi/fPGOD92/Oymd2w
    14. OyEH8bnMvcxWEPHDKXSc9qlfNHl22j66KL8jVEbMSf/l2IPafssW8/QFqdyCdmLS
    15. qTwt3qhTE5lJROlDVoqZWIMCq6VPpEeA2aet29kCgYAD0ejg6OGB6KDTt0kUG4H4
    16. u2vYr2uEYFI9RptafExW0OF+97afG4FeSQfoz4jMgngu51wEWSrRBLKt2TQ80a9z
    17. 565nRIkVgdmfWPdJ09zh8bSm5bzedi8PeQrjZbhH2idcS+F6zncPaHb56L2/IYxr
    18. 8Smz78ezIZoug9DrKo1acQKBgQC3aS4ISu6lAS2a++FSTtztwtM+BE22yF4k9U5J
    19. iHa6QtgY4RPbSQbyjJY92Nqwz+zjUv5;ñvT4k
    Alles anzeigen
  • 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.


    Quellcode

    1. -----BEGIN DH PARAMETERS-----
    2. MIIBCAKCAQEAsbliBfUhTnrGVwBQGT7fVpNX8rqP0XgEsN79wslNxFZr4cC5rZ0k
    3. IgP8QnFW1l0C7J1HzDqjcPsyuXAKgcu4nMe6G81s0jQlt2xoBKzbOiGwPNx3ehMs
    4. h+NqOSWkJo1j87IPXLtbyyLtIPYeLtFQ1ihkGulvsxLQAwbFkqu29oC6l+1Nffvr
    5. tJIoVt9p0jtEk+qih+gUG/yXpeWlXFeAZbuYtgyMs/NowZx3LdziLf8hE5sYnBUp
    6. mseYBxu9SWe3fy35pM3zN6pG5GkZyoHgtAl2odNHeKtV4fesyQeBwRFv98ZnBFvN
    7. 7mANau2qBh4lPNksKrDMlsJAQnwzGORXIwIBAg==
    8. -----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".


    Quellcode

    1. -----BEGIN RSA PRIVATE KEY-----
    2. MIIEpAIBAAKCAQEAtUlL5U+e2jaaAIC2h3JMIgc0EaYM3rjjGVgsq2QQZ8nTGUBw
    3. o5G+3LVrxmpP33oRcoVffacDqCBhPKGYudd7EzYji8hsQIiGCavU60KPj+JAhzbq
    4. XylcKnRUIZi2FLq7DN5PNyUMXQVwGv6bgmq+fGwNjpUBfxKjS1WzzjlLAVBOeoRh
    5. bbqgiZQ0Bvg4rxek3G+r7vDtMGg4cakHnCQk/nb6ZVa3aGRrTCcDegInZrdYk0ch
    6. 67VuxAVoNDZoqbvAQWiAVK33NE1yZ9B+mySuHIHJH7/tYR9rTbqtKWwKbt6r+TVP
    7. 3upKdrMkopxoy8hETzIn5c5z5b4tl5+Pya/KHQIDAQABAoIBAG91v0of6AU2aP1C
    8. JfelGJYbY7IuK9+MQWTFx8Eg5s1JU5dE/Xw0EetVSAxYNP+r56pHwmxZEXB/aAmF
    9. OYeZqrwnHzfEZHpQ9khf86sp42aNryrzYqpbnaUknM2DPQAFxxekX4QCLVXMEB8o
    10. x6gpxTBupu8xQhhE901MRh7XLvyAwLJ8qpYbF2dpimb2/EoUsjb/let6W55pA5bJ
    11. Y9nzCaX5NPU8fHjgvHzaa9dCbUv9lAhQJLQtBkSyPB5fuw1tMY7VmVsxNURunNjV
    12. eREJ/r2fQuuPEEkrtRfzmFDwL+w8D505jV5ofxdN4qC+74YAecel6Vlb4uOMtIcv
    13. MUlZ3kECgYEA2hLjMXOa74dMyZ0qrhFpTs4tg9mwkVuQ254FmHOyMx2BTd9Z09/+
    14. nYZJjbOl61I3m/7eChNv/FLjId6R2EoYcDJ3SrCxEZoemDb/uyC3QpWKZG9yN/vh
    15. JmDcayyHClrOmFxFSD0SQeaqAbiQeScly7nmYKpJysVr9NmErdG7ieUCgYEA1NCN
    16. WHfVEZNu6LN3jELSj5FXTqdMo5fr+QSAdinc0pnzIG4kHa6pi/fPGOD92/Oymd2w
    17. OyEH8bnMvcxWEPHDKXSc9qlfNHl22j66KL8jVEbMSf/l2IPafssW8/QFqdyCdmLS
    18. qTwt3qhTE5lJROlDVoqZWIMCq6VPpEeA2aet29kCgYAD0ejg6OGB6KDTt0kUG4H4
    19. u2vYr2uEYFI9RptafExW0OF+97afG4FeSQfoz4jMgngu51wEWSrRBLKt2TQ80a9z
    20. 565nRIkVgdmfWPdJ09zh8bSm5bzedi8PeQrjZbhH2idcS+F6zncPaHb56L2/IYxr
    21. 8Smz78ezIZoug9DrKo1acQKBgQC3aS4ISu6lAS2a++FSTtztwtM+BE22yF4k9U5J
    22. iHa6QtgY4RPbSQbyjJY92Nqwz+zjUv5pV2RjXkAoa4zZeaM7fTcyFnLo5K4cFeeW
    23. 6nRmU8YJGLRcz/ZlRF75zRt8c4E0yqLIHAdkWCmRQJC3BVp1oWnbsL2CdSyYZs+T
    24. xkG+sQKBgQCYtxjh6dQkWgLf9Wm4hrDYs6FABdGxGmkW6UZlescPiRbNysECxzQQ
    25. sYmu0nGrzcLDY25YEZSNEuige9GmaBnfcSX4mD3VVcZ9HuqHvzSfmIfVWd6amR7Q
    26. YnTNi1WKMjmiHb+IiXW9jlvMbVlAB0C4snQLCh15tw4aBtTCWPEsUw==
    27. -----END RSA PRIVATE KEY-----
    Alles anzeigen
    (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^^

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von Mindfreak ()

  • 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)docs.oracle.com/javase/7/docs/…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 :/
  • 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();
    Ein Feedback auf Tipps ist auch schön. :P

    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von jogimuc ()