Ja super Sache! Läuft!
Da sag ich mal Herzlichen dank für die Hilfe von euch Beiden.
Ja super Sache! Läuft!
Da sag ich mal Herzlichen dank für die Hilfe von euch Beiden.
gut ich habe jetzt das temp im thread untergebracht.
Ich frag mich nur wie ich das mit dem Answer.setText("SERVER SAID: "+line); bauen soll
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.util.Log;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
public class MainActivity extends Activity {
// Inistailierung
Button Send;
EditText IP;
EditText Port;
TextView Answer;
EditText Message;
private String ip_address;
private int port = 11880;
private SSLSocket socket = null;
private BufferedReader in = null;
private BufferedWriter out = null;
private final String TAG = "TAG";
private char keystorepass[] = "key12345".toCharArray();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Send = (Button) findViewById(R.id.btnSend);
IP = (EditText) findViewById(R.id.etIP);
Port = (EditText) findViewById(R.id.etPort);
Answer = (TextView) findViewById(R.id.tvAnswer);
Message = (EditText) findViewById(R.id.etMessage);
Send.setClickable(true);
Send.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(final View v) {
if (IP.getText().toString().equals(null) || Port.getText().toString().equals(null)){
}else {
final String temp = Message.getText().toString();
chat(temp);
port = Integer.parseInt(Port.getText().toString());
ip_address = IP.getText().toString();
try{
new Thread() {
@Override
public void run() {
try {
KeyStore ks = KeyStore.getInstance("BKS");
InputStream keyin = getApplicationContext().getResources().openRawResource(R.raw.neuserverkeypem);
ks.load(keyin,keystorepass);
org.apache.http.conn.ssl.SSLSocketFactory socketFactory = new org.apache.http.conn.ssl.SSLSocketFactory(ks);
socketFactory.setHostnameVerifier(socketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
socket = (SSLSocket)
socketFactory.createSocket(new Socket(ip_address,port), ip_address, port, false);
socket.startHandshake();
printServerCertificate(socket);
printSocketInfo(socket);
out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
} catch (UnknownHostException e) {
Log.i(TAG,"Unknown host");
//System.exit(1);
} catch (IOException e) {
Log.i(TAG,"No I/O");
e.printStackTrace();
//System.exit(1);
} catch (KeyStoreException e) {
Log.i(TAG,"Keystore ks error");
//System.exit(-1);
} catch (NoSuchAlgorithmException e) {
Log.i(TAG,"No such algorithm for ks.load");
e.printStackTrace();
//System.exit(-1);
} catch (CertificateException e) {
Log.i(TAG,"certificate missing");
e.printStackTrace();
//System.exit(-1);
} catch (UnrecoverableKeyException e) {
Log.i(TAG,"unrecoverableKeyException");
e.printStackTrace();
//System.exit(-1);
} catch (KeyManagementException e) {
Log.i(TAG,"key management exception");
e.printStackTrace();
//System.exit(-1);
}
}
}.start();
}
catch(Exception ex){}
}
}
});
}
private void printServerCertificate(SSLSocket socket) {
try {
Certificate[] serverCerts =
socket.getSession().getPeerCertificates();
for (int i = 0; i < serverCerts.length; i++) {
Certificate myCert = serverCerts[i];
Log.i(TAG,"====Certificate:" + (i+1) + "====");
Log.i(TAG,"-Public Key-\n" + myCert.getPublicKey());
Log.i(TAG,"-Certificate Type-\n " + myCert.getType());
System.out.println();
}
} catch (SSLPeerUnverifiedException e) {
Log.i(TAG,"Could not verify peer");
e.printStackTrace();
System.exit(-1);
}
}
private void printSocketInfo(SSLSocket s) {
Log.i(TAG,"Socket class: "+s.getClass());
Log.i(TAG," Remote address = "
+s.getInetAddress().toString());
Log.i(TAG," Remote port = "+s.getPort());
Log.i(TAG," Local socket address = "
+s.getLocalSocketAddress().toString());
Log.i(TAG," Local address = "
+s.getLocalAddress().toString());
Log.i(TAG," Local port = "+s.getLocalPort());
Log.i(TAG," Need client authentication = "
+s.getNeedClientAuth());
SSLSession ss = s.getSession();
Log.i(TAG," Cipher suite = "+ss.getCipherSuite());
Log.i(TAG," Protocol = "+ss.getProtocol());
}
public void chat(String temp){
String message = temp;
String line = "";
// send id of the device to match with the image
try {
out.write(message+"\n");
out.flush();
} catch (IOException e2) {
Log.i(TAG,"Read failed");
System.exit(1);
}
// receive a ready command from the server
try {
line = in.readLine();
Answer.setText("SERVER SAID: "+line);
//Log.i(TAG,line);
} catch (IOException e1) {
Log.i(TAG,"Read failed");
System.exit(1);
}
}
}
Alles anzeigen
10-11 12:46:30.890 3995-3995/? I/art: Late-enabling -Xcheck:jni
10-11 12:46:30.890 3995-3995/? W/art: Unexpected CPU variant for X86 using defaults: x86
10-11 12:46:31.013 3995-3995/com.example.dddddddddd.aaa W/System: ClassLoader referenced unknown path: /data/app/com.example.dddddddddd.aaa-2/lib/x86
10-11 12:46:31.022 3995-3995/com.example.dddddddddd.aaa I/InstantRun: starting instant run server: is main process
10-11 12:46:31.196 3995-4011/com.example.dddddddddd.aaa D/libEGL: Emulator has host GPU support, qemu.gles is set to 1.
10-11 12:46:31.197 3995-4011/com.example.dddddddddd.aaa E/libEGL: load_driver(/system/lib/egl/libGLES_emulation.so): dlopen failed: library "/system/lib/egl/libGLES_emulation.so" not found
10-11 12:46:31.198 3995-4011/com.example.dddddddddd.aaa D/libEGL: loaded /system/lib/egl/libEGL_emulation.so
loaded /system/lib/egl/libGLESv1_CM_emulation.so
10-11 12:46:31.204 3995-4011/com.example.dddddddddd.aaa D/libEGL: loaded /system/lib/egl/libGLESv2_emulation.so
10-11 12:46:31.224 3995-4011/com.example.dddddddddd.aaa I/OpenGLRenderer: Initialized EGL, version 1.4
10-11 12:46:31.224 3995-4011/com.example.dddddddddd.aaa D/OpenGLRenderer: Swap behavior 1
10-11 12:46:31.311 3995-4011/com.example.dddddddddd.aaa E/EGL_emulation: tid 4011: eglSurfaceAttrib(1174): error 0x3009 (EGL_BAD_MATCH)
10-11 12:46:31.311 3995-4011/com.example.dddddddddd.aaa W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0xdb2f2da0, error=EGL_BAD_MATCH
10-11 12:46:31.791 3995-3995/com.example.dddddddddd.aaa I/Choreographer: Skipped 32 frames! The application may be doing too much work on its main thread.
10-11 12:46:33.429 3995-3995/com.example.dddddddddd.aaa W/IInputConnectionWrapper: finishComposingText on inactive InputConnection
10-11 12:46:40.113 3995-3995/com.example.dddddddddd.aaa W/IInputConnectionWrapper: finishComposingText on inactive InputConnection
10-11 12:46:42.547 3995-3995/com.example.dddddddddd.aaa W/IInputConnectionWrapper: finishComposingText on inactive InputConnection
10-11 12:46:44.865 3995-3995/com.example.dddddddddd.aaa W/IInputConnectionWrapper: finishComposingText on inactive InputConnection
10-11 12:46:46.390 3995-4024/com.example.dddddddddd.aaa I/TAG: ====Certificate:1====
-Public Key-
OpenSSLRSAPublicKey{modulus=b5494be54f9eda369a0080b687724c22073411a60cdeb8e319582cab641067c9d3194070a391bedcb56bc66a4fdf7a1172855f7da703a820613ca198b9d77b1336238bc86c40888609abd4eb428f8fe2408736ea5f295c2a74542198b614babb0cde4f37250c5d05701afe9b826abe7c6c0d8e95017f12a34b55b3ce394b01504e7a84616dbaa089943406f838af17a4dc6fabeef0ed30683871a9079c2424fe76fa6556b768646b4c27037a022766b758934721ebb56ec40568343668a9bbc041688054adf7344d7267d07e9b24ae1c81c91fbfed611f6b4dbaad296c0a6edeabf9354fdeea4a76b324a29c68cbc8444f3227e5ce73e5be2d979f8fc9afca1d,publicExponent=10001}
-Certificate Type-
X.509
Socket class: class com.android.org.conscrypt.OpenSSLSocketImplWrapper
Remote address = /136.243.44.109
10-11 12:46:46.391 3995-4024/com.example.dddddddddd.aaa I/TAG: Remote port = 11880
Local socket address = /10.0.3.15:33506
Local address = /10.0.3.15
Local port = 33506
Need client authentication = false
Cipher suite = TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
Protocol = TLSv1.2
10-11 12:46:46.419 3995-4024/com.example.dddddddddd.aaa E/AndroidRuntime: FATAL EXCEPTION: Thread-4
Process: com.example.dddddddddd.aaa, PID: 3995
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6891)
at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:1083)
at android.view.ViewGroup.invalidateChild(ViewGroup.java:5205)
at android.view.View.invalidateInternal(View.java:13656)
at android.view.View.invalidate(View.java:13620)
at android.view.View.invalidate(View.java:13604)
at android.widget.TextView.checkForRelayout(TextView.java:7347)
at android.widget.TextView.setText(TextView.java:4480)
at android.widget.TextView.setText(TextView.java:4337)
at android.widget.TextView.setText(TextView.java:4312)
at com.example.oliverlenk.pmt.MainActivity.chat(MainActivity.java:167)
at com.example.oliverlenk.pmt.MainActivity$1$1.run(MainActivity.java:84)
10-11 12:46:47.093 3995-4011/com.example.dddddddddd.aaa D/OpenGLRenderer: endAllActiveAnimators on 0xd6059e80 (RippleDrawable) with handle 0xe32f8300
Alles anzeigen
Die Toast hab ich auch rausgenommen
Hier nochmal der Fehlercode,
E/AndroidRuntime: FATAL EXCEPTION: Thread-4
Process: com.example.ccccc.vvvv, PID: 3288
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6891)
at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:1083)
at android.view.ViewGroup.invalidateChild(ViewGroup.java:5205)
at android.view.View.invalidateInternal(View.java:13656)
at android.view.View.invalidate(View.java:13620)
at android.view.View.invalidate(View.java:13604)
at android.widget.TextView.checkForRelayout(TextView.java:7347)
at android.widget.TextView.setText(TextView.java:4480)
at android.widget.TextView.setText(TextView.java:4337)
at android.widget.TextView.setText(TextView.java:4312)
at com.example.vvvv.ccc.MainActivity.chat(MainActivity.java:176)
at com.example.vvvvv.ccc.MainActivity$1$1.run(MainActivity.java:86)
Alles anzeigen
um den Rest kümmer ich mich jetzt mal. Ich nehme jeden Hinweis dankend an. Bin noch kein Pro und ist noch ein Harter Kampf für mich mit Java
Schau bitte nochmal drüber. Selbe Fehlermeldung noch.
ublic void onClick(final View v) {
if (IP.getText().toString().equals(null) || Port.getText().toString().equals(null)){
Toast.makeText(getApplicationContext(), "Bitte IP und Port eingeben", Toast.LENGTH_LONG).show();
}else {
final String temp = Message.getText().toString();
if (temp == null){
}
port = Integer.parseInt(Port.getText().toString());
ip_address = IP.getText().toString();
try{
//HIER DEN NETZWERK-OPERATIONEN IN NEUEN THREAD STARTEN
new Thread() {
@Override
public void run() {
try {
KeyStore ks = KeyStore.getInstance("BKS");
InputStream keyin = getApplicationContext().getResources().openRawResource(R.raw.neuserverkeypem);
ks.load(keyin,keystorepass);
org.apache.http.conn.ssl.SSLSocketFactory socketFactory = new org.apache.http.conn.ssl.SSLSocketFactory(ks);
socketFactory.setHostnameVerifier(socketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
socket = (SSLSocket)
socketFactory.createSocket(new Socket(ip_address,port), ip_address, port, false);
socket.startHandshake();
printServerCertificate(socket);
printSocketInfo(socket);
out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
chat(temp);
} catch (UnknownHostException e) {
Toast.makeText(getApplicationContext(), "Unknown host", Toast.LENGTH_SHORT).show();
Log.i(TAG,"Unknown host");
//System.exit(1);
} catch (IOException e) {
Toast.makeText(getApplicationContext(), "No I/O", Toast.LENGTH_SHORT).show();
Log.i(TAG,"No I/O");
e.printStackTrace();
//System.exit(1);
} catch (KeyStoreException e) {
Toast.makeText(getApplicationContext(), "Keystore ks error", Toast.LENGTH_SHORT).show();
Log.i(TAG,"Keystore ks error");
//System.exit(-1);
} catch (NoSuchAlgorithmException e) {
Toast.makeText(getApplicationContext(), "No such algorithm for ks.load", Toast.LENGTH_SHORT).show();
Log.i(TAG,"No such algorithm for ks.load");
e.printStackTrace();
//System.exit(-1);
} catch (CertificateException e) {
Toast.makeText(getApplicationContext(), "certificate missing", Toast.LENGTH_SHORT).show();
Log.i(TAG,"certificate missing");
e.printStackTrace();
//System.exit(-1);
} catch (UnrecoverableKeyException e) {
Toast.makeText(getApplicationContext(), "UnrecoverableKeyException", Toast.LENGTH_SHORT).show();
Log.i(TAG,"unrecoverableKeyException");
e.printStackTrace();
//System.exit(-1);
} catch (KeyManagementException e) {
Toast.makeText(getApplicationContext(), "KeyManagementException", Toast.LENGTH_SHORT).show();
Log.i(TAG,"key management exception");
e.printStackTrace();
//System.exit(-1);
}
}
}.start();
}
catch(Exception ex){}
}
}
Alles anzeigen
Wie meinst du das das? v wird doch eigentlich im Thread gebraucht? Habs versucht, aber die App crasht nach wie vor
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.
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.
-----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".
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAtUlL5U+e2jaaAIC2h3JMIgc0EaYM3rjjGVgsq2QQZ8nTGUBw
o5G+3LVrxmpP33oRcoVffacDqCBhPKGYudd7EzYji8hsQIiGCavU60KPj+JAhzbq
XylcKnRUIZi2FLq7DN5PNyUMXQVwGv6bgmq+fGwNjpUBfxKjS1WzzjlLAVBOeoRh
bbqgiZQ0Bvg4rxek3G+r7vDtMGg4cakHnCQk/nb6ZVa3aGRrTCcDegInZrdYk0ch
67VuxAVoNDZoqbvAQWiAVK33NE1yZ9B+mySuHIHJH7/tYR9rTbqtKWwKbt6r+TVP
3upKdrMkopxoy8hETzIn5c5z5b4tl5+Pya/KHQIDAQABAoIBAG91v0of6AU2aP1C
JfelGJYbY7IuK9+MQWTFx8Eg5s1JU5dE/Xw0EetVSAxYNP+r56pHwmxZEXB/aAmF
OYeZqrwnHzfEZHpQ9khf86sp42aNryrzYqpbnaUknM2DPQAFxxekX4QCLVXMEB8o
x6gpxTBupu8xQhhE901MRh7XLvyAwLJ8qpYbF2dpimb2/EoUsjb/let6W55pA5bJ
Y9nzCaX5NPU8fHjgvHzaa9dCbUv9lAhQJLQtBkSyPB5fuw1tMY7VmVsxNURunNjV
eREJ/r2fQuuPEEkrtRfzmFDwL+w8D505jV5ofxdN4qC+74YAecel6Vlb4uOMtIcv
MUlZ3kECgYEA2hLjMXOa74dMyZ0qrhFpTs4tg9mwkVuQ254FmHOyMx2BTd9Z09/+
nYZJjbOl61I3m/7eChNv/FLjId6R2EoYcDJ3SrCxEZoemDb/uyC3QpWKZG9yN/vh
JmDcayyHClrOmFxFSD0SQeaqAbiQeScly7nmYKpJysVr9NmErdG7ieUCgYEA1NCN
WHfVEZNu6LN3jELSj5FXTqdMo5fr+QSAdinc0pnzIG4kHa6pi/fPGOD92/Oymd2w
OyEH8bnMvcxWEPHDKXSc9qlfNHl22j66KL8jVEbMSf/l2IPafssW8/QFqdyCdmLS
qTwt3qhTE5lJROlDVoqZWIMCq6VPpEeA2aet29kCgYAD0ejg6OGB6KDTt0kUG4H4
u2vYr2uEYFI9RptafExW0OF+97afG4FeSQfoz4jMgngu51wEWSrRBLKt2TQ80a9z
565nRIkVgdmfWPdJ09zh8bSm5bzedi8PeQrjZbhH2idcS+F6zncPaHb56L2/IYxr
8Smz78ezIZoug9DrKo1acQKBgQC3aS4ISu6lAS2a++FSTtztwtM+BE22yF4k9U5J
iHa6QtgY4RPbSQbyjJY92Nqwz+zjUv5pV2RjXkAoa4zZeaM7fTcyFnLo5K4cFeeW
6nRmU8YJGLRcz/ZlRF75zRt8c4E0yqLIHAdkWCmRQJC3BVp1oWnbsL2CdSyYZs+T
xkG+sQKBgQCYtxjh6dQkWgLf9Wm4hrDYs6FABdGxGmkW6UZlescPiRbNysECxzQQ
sYmu0nGrzcLDY25YEZSNEuige9GmaBnfcSX4mD3VVcZ9HuqHvzSfmIfVWd6amR7Q
YnTNi1WKMjmiHb+IiXW9jlvMbVlAB0C4snQLCh15tw4aBtTCWPEsUw==
-----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^^
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.
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
test
ANau2qBh4lPNksKrDMlsJAQnwzGORXIwIBAg==
-----END DH PARAMETERS-----
S-----
lGJYbY7IuK9+MQWTFx8Eg5s1JU5dE/Xw0EetVSAxYNP+r56pHwmxZEXB/aAmF
OYeZqrwnHzfEZHpQ9khf86sp42aNryrzYqpbnaUknM2DPQAFxxekX4QCLVXMEB8o
x6gpxTBupu8xQhhE901MRh7XLvyAwLJ8qpYbF2dpimb2/EoUsjb/let6W55pA5bJ
Y9nzCaX5NPU8fHjgvHzaa9dCbUv9lAhQJLQtBkSyPB5fuw1tMY7VmVsxNURunNjV
eREJ/r2fQuuPEEkrtRfzmFDwL+w8D505jV5ofxdN4qC+74YAecel6Vlb4uOMtIcv
MUlZ3kECgYEA2hLjMXOa74dMyZ0qrhFpTs4tg9mwkVuQ254FmHOyMx2BTd9Z09/+
nYZJjbOl61I3m/7eChNv/FLjId6R2EoYcDJ3SrCxEZoemDb/uyC3QpWKZG9yN/vh
JmDcayyHClrOmFxFSD0SQeaqAbiQeScly7nmYKpJysVr9NmErdG7ieUCgYEA1NCN
WHfVEZNu6LN3jELSj5FXTqdMo5fr+QSAdinc0pnzIG4kHa6pi/fPGOD92/Oymd2w
OyEH8bnMvcxWEPHDKXSc9qlfNHl22j66KL8jVEbMSf/l2IPafssW8/QFqdyCdmLS
qTwt3qhTE5lJROlDVoqZWIMCq6VPpEeA2aet29kCgYAD0ejg6OGB6KDTt0kUG4H4
u2vYr2uEYFI9RptafExW0OF+97afG4FeSQfoz4jMgngu51wEWSrRBLKt2TQ80a9z
565nRIkVgdmfWPdJ09zh8bSm5bzedi8PeQrjZbhH2idcS+F6zncPaHb56L2/IYxr
8Smz78ezIZoug9DrKo1acQKBgQC3aS4ISu6lAS2a++FSTtztwtM+BE22yF4k9U5J
iHa6QtgY4RPbSQbyjJY92Nqwz+zjUv5;ñvT4k
Alles anzeigen
Danke für die Info, ich bring es mal zeitnah in mein code mit rein! Melde mich nach erfolg
Abend,
ich hau mal ein Java Code rein damit es vielleicht die ein oder andere Frage klärt.
public class MainActivity extends Activity {
// Inistailierung
Button Send;
EditText IP;
EditText Port;
TextView Answer;
EditText Message;
private String ip_address;
private int port = 11880;
private SSLSocket socket = null;
private BufferedReader in = null;
private BufferedWriter out = null;
private final String TAG = "TAG";
private char keystorepass[] = "key12345".toCharArray();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Send = (Button) findViewById(R.id.btnSend);
IP = (EditText) findViewById(R.id.etIP);
Port = (EditText) findViewById(R.id.etPort);
Answer = (TextView) findViewById(R.id.tvAnswer);
Message = (EditText) findViewById(R.id.etMessage);
Send.setClickable(true);
Send.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (IP.getText().toString().equals(null) || Port.getText().toString().equals(null)){
Toast.makeText(v.getContext(), "Bitte IP und Port eingeben", Toast.LENGTH_LONG).show();
}else {
String temp = Message.getText().toString();
if (temp == null){
temp = "Es wurde keine Nachricht eingegeben";
}
port = Integer.parseInt(Port.getText().toString());
ip_address = IP.getText().toString();
try {
KeyStore ks = KeyStore.getInstance("BKS");
InputStream keyin = v.getResources().openRawResource(R.raw.neuserverkeypem);
ks.load(keyin,keystorepass);
org.apache.http.conn.ssl.SSLSocketFactory socketFactory = new org.apache.http.conn.ssl.SSLSocketFactory(ks);
socketFactory.setHostnameVerifier(socketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
socket = (SSLSocket)
socketFactory.createSocket(new Socket(ip_address,port), ip_address, port, false);
socket.startHandshake();
printServerCertificate(socket);
printSocketInfo(socket);
out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
chat(temp);
} catch (UnknownHostException e) {
Toast.makeText(v.getContext(), "Unknown host", Toast.LENGTH_SHORT).show();
Log.i(TAG,"Unknown host");
//System.exit(1);
} catch (IOException e) {
Toast.makeText(v.getContext(), "No I/O", Toast.LENGTH_SHORT).show();
Log.i(TAG,"No I/O");
e.printStackTrace();
//System.exit(1);
} catch (KeyStoreException e) {
Toast.makeText(v.getContext(), "Keystore ks error", Toast.LENGTH_SHORT).show();
Log.i(TAG,"Keystore ks error");
//System.exit(-1);
} catch (NoSuchAlgorithmException e) {
Toast.makeText(v.getContext(), "No such algorithm for ks.load", Toast.LENGTH_SHORT).show();
Log.i(TAG,"No such algorithm for ks.load");
e.printStackTrace();
//System.exit(-1);
} catch (CertificateException e) {
Toast.makeText(v.getContext(), "certificate missing", Toast.LENGTH_SHORT).show();
Log.i(TAG,"certificate missing");
e.printStackTrace();
//System.exit(-1);
} catch (UnrecoverableKeyException e) {
Toast.makeText(v.getContext(), "UnrecoverableKeyException", Toast.LENGTH_SHORT).show();
Log.i(TAG,"unrecoverableKeyException");
e.printStackTrace();
//System.exit(-1);
} catch (KeyManagementException e) {
Toast.makeText(v.getContext(), "KeyManagementException", Toast.LENGTH_SHORT).show();
Log.i(TAG,"key management exception");
e.printStackTrace();
//System.exit(-1);
}
}
}
});
}
private void printServerCertificate(SSLSocket socket) {
try {
Certificate[] serverCerts =
socket.getSession().getPeerCertificates();
for (int i = 0; i < serverCerts.length; i++) {
Certificate myCert = serverCerts[i];
Log.i(TAG,"====Certificate:" + (i+1) + "====");
Log.i(TAG,"-Public Key-\n" + myCert.getPublicKey());
Log.i(TAG,"-Certificate Type-\n " + myCert.getType());
System.out.println();
}
} catch (SSLPeerUnverifiedException e) {
Log.i(TAG,"Could not verify peer");
e.printStackTrace();
System.exit(-1);
}
}
private void printSocketInfo(SSLSocket s) {
Log.i(TAG,"Socket class: "+s.getClass());
Log.i(TAG," Remote address = "
+s.getInetAddress().toString());
Log.i(TAG," Remote port = "+s.getPort());
Log.i(TAG," Local socket address = "
+s.getLocalSocketAddress().toString());
Log.i(TAG," Local address = "
+s.getLocalAddress().toString());
Log.i(TAG," Local port = "+s.getLocalPort());
Log.i(TAG," Need client authentication = "
+s.getNeedClientAuth());
SSLSession ss = s.getSession();
Log.i(TAG," Cipher suite = "+ss.getCipherSuite());
Log.i(TAG," Protocol = "+ss.getProtocol());
}
public void chat(String temp){
String message = temp;
String line = "";
// send id of the device to match with the image
try {
out.write(message+"\n");
out.flush();
} catch (IOException e2) {
Log.i(TAG,"Read failed");
System.exit(1);
}
// receive a ready command from the server
try {
line = in.readLine();
Answer.setText("SERVER SAID: "+line);
//Log.i(TAG,line);
} catch (IOException e1) {
Log.i(TAG,"Read failed");
System.exit(1);
}
}
}
Alles anzeigen
was ich bisher erfahren habe, ist das die diese Methode veraltet ist. Laut aussagen muss man in AsyncTask die ganze Sache schreiben.
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.
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.
Das schreib ich heute Abend. Bin unterwegs und habs gerade nicht zur Hand. Die C++ Codes hab ich auch nur, weils in ner CLoud von mir lag^^.
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)
#include <cstdlib>
#include <iostream>
#include <boost/bind.hpp>
#include <boost/asio.hpp>
#include <boost/asio/ssl.hpp>
#include <string>
enum { max_length = 1024 };
class client
{
public:
client(boost::asio::io_context& io_context,
boost::asio::ssl::context& context,
boost::asio::ip::tcp::resolver::results_type endpoints)
: socket_(io_context, context)
{
socket_.set_verify_mode(boost::asio::ssl::verify_peer);
socket_.set_verify_callback(
boost::bind(&client::verify_certificate, this, _1, _2));
boost::asio::async_connect(socket_.lowest_layer(), endpoints,
boost::bind(&client::handle_connect, this,
boost::asio::placeholders::error));
}
bool verify_certificate(bool preverified,
boost::asio::ssl::verify_context& ctx)
{
char subject_name[256];
X509* cert = X509_STORE_CTX_get_current_cert(ctx.native_handle());
X509_NAME_oneline(X509_get_subject_name(cert), subject_name, 256);
return preverified;
}
void handle_connect(const boost::system::error_code& error)
{
if (!error)
{
socket_.async_handshake(boost::asio::ssl::stream_base::client,
boost::bind(&client::handle_handshake, this,
boost::asio::placeholders::error));
}
else
{
std::cout << "Connect failed: " << error.message() << "\n";
}
}
void handle_handshake(const boost::system::error_code& error)
{
if (!error)
{
std::cout << "Enter message: ";
std::cin.getline(request_, max_length);
size_t request_length = strlen(request_);
boost::asio::async_write(socket_,
boost::asio::buffer(request_),
boost::bind(&client::handle_write, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
else
{
std::cout << "Handshake failed: " << error.message() << "\n";
}
}
void handle_write(const boost::system::error_code& error,
size_t bytes_transferred)
{
if (!error)
{
reply_.fill(0);
socket_.async_read_some(boost::asio::buffer(reply_, 1024),
boost::bind(&client::handle_read, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
else
{
std::cout << "Write failed: " << error.message() << "\n";
}
}
void handle_read(const boost::system::error_code& error,
size_t bytes_transferred)
{
if (!error)
{
size_t length = bytes_transferred;
std::string test;
for (UINT i = 0; i < length; i++) {
test += reply_[i];
}
std::cout << test;
std::cout << "\n";
}
else
{
std::cout << "Read failed: " << error.message() << "\n";
}
}
private:
boost::asio::ssl::stream<boost::asio::ip::tcp::socket> socket_;
char request_[max_length];
std::array<char, 1024> reply_;
};
int main() {
try {
while (true) {
boost::asio::io_context io_context;
boost::asio::ip::tcp::resolver resolver(io_context);
boost::asio::ip::tcp::resolver::results_type endpoints = resolver.resolve("127.0.0.1", "11880");
boost::asio::ssl::context ctx(boost::asio::ssl::context::sslv23);
ctx.load_verify_file("public.pem");
client c(io_context, ctx, endpoints);
io_context.run();
std::cin.get();
}
}
catch (std::exception& myexc) {
std::cerr << "Exception: " << myexc.what() << "\n";
std::cin.get();
}
return 0;
}
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^^.
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:
#include <iostream>
#include <string>
#include <array>
#include <boost/bind.hpp>
#include <boost/asio.hpp>
#include <boost/asio/ssl.hpp>
typedef boost::asio::ssl::stream<boost::asio::ip::tcp::socket> ssl_socket;
std::string pass() {
return "test";
}
int main() {
std::cout << "Server started..." << std::endl;
while (true) {
try {
//Start TLS Socket
boost::asio::io_context io_context;
boost::asio::ip::tcp::acceptor acceptor(io_context, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), 11880));
boost::asio::ssl::context context(boost::asio::ssl::context::sslv23);
context.set_options(
boost::asio::ssl::context::default_workarounds
| boost::asio::ssl::context::no_sslv2);
context.use_certificate_chain_file("public.pem");
context.set_password_callback(boost::bind(pass));
context.use_private_key_file("private.pem", boost::asio::ssl::context::pem);
context.use_tmp_dh_file("dh2048.pem");
ssl_socket stream(io_context, context);
boost::asio::ip::tcp::endpoint peer_endpoint;
acceptor.accept(stream.lowest_layer(), peer_endpoint);
boost::system::error_code ec;
stream.handshake(boost::asio::ssl::stream_base::server, ec);
std::string response;
std::string incoming;
std::array<char, 1024> buffer;
buffer.fill(0);
boost::system::error_code error;
stream.read_some(boost::asio::buffer(buffer, sizeof(buffer)), error); //Nachricht kommt an
incoming = buffer.data();
std::cout << incoming << std::endl;
response += "ist angekommen: (" + incoming + ")"; //Antwort = "ist angekommen (%meineNachricht%)"
boost::asio::write(stream, boost::asio::buffer(response, response.length())); //Antwort senden
}
catch (std::exception& myexc) {
std::cout << myexc.what() << std::endl;
}
}
}
Alles anzeigen
Ich muss leider erstmal los. Melde mich heute Abend wieder
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.