Socket Verschlüsselte Kommunikation - Fehler

MR_UNIX

Bekanntes Mitglied
Hallo,

ich bin soeben auf ein mir bisher unbekanntes Problem gestoßen und mir ist leider auch nach 1 1/2 Stunden Recherche immer noch unklar, wie ich dieses am besten lösen kann.

Mein Ziel ist es, ein Message Objekt im Internet zu verschicken. Das an sich ist kein Problem. Wo es aber hapert, ist die Verschlüsselung. Denn ich möchte dieses Objekt, welches später sensible Daten enthalten wird eben logischerweise nicht im Klartext durch die halbe Welt schicken, sondern mit AES und einem Passwort verschlüsseln.

Die beteiligten Komponenten sind folgende: ClientHandler, EncryptionUtility, Message, ReadWriteAES, Testclient
Hier der entsprechende Quellcode:

Testclient.java
Java:
package de.mrpixeldream.dreamcode.im.client.test;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;

import org.jasypt.util.text.StrongTextEncryptor;

import de.mrpixeldream.dreamcode.im.server.io.Message;

public class Testclient
{
	static final String globalPassword = "mein_passwort";
	
	static Socket testserver;
	static String serverResponse = "";
	
	static StrongTextEncryptor encryptor = new StrongTextEncryptor();
	
	public static void main(String[] args)
	{	
		try
		{
			encryptor.setPassword(globalPassword);
			
			System.out.println("Connecting to test server...");
			testserver = new Socket("127.0.0.1", 22558);
			
			System.out.println("Initializing streams...");
			ByteArrayOutputStream bos = new ByteArrayOutputStream();
			ObjectOutputStream objectOut = new ObjectOutputStream(bos);
			
			System.out.println("Waiting for ACK flag from server...");
			serverResponse = new BufferedReader(new InputStreamReader(testserver.getInputStream())).readLine();
			System.out.println("Response: " + serverResponse);
			
			if (serverResponse.equals("ACK"))
			{
				System.out.println("Logging in with test account...");
				System.out.println("Out: LOGIN MrPixelDream hier_steht_ein_passwort");
				
				PrintWriter writer = new PrintWriter(new OutputStreamWriter(testserver.getOutputStream()));
				writer.println("LOGIN MrPixelDream hier_steht_ein_passwort");
				writer.flush();
				serverResponse = new BufferedReader(new InputStreamReader(testserver.getInputStream())).readLine();
				
				System.out.println("Response: " + serverResponse);
				
				System.out.println("Broadcasting test message...");
				System.out.println("Out: BROADCAST test");
				
				Message testBroadcast = new Message("BROADCAST", new String[] { "test" });
				objectOut.writeObject(testBroadcast);
				objectOut.flush();
				
				ReadWriteAES.encode(bos.toByteArray(), testserver.getOutputStream(), globalPassword);
				
				ByteArrayInputStream bis = new ByteArrayInputStream(ReadWriteAES.decode(testserver.getInputStream(), globalPassword));
				ObjectInputStream objectIn = new ObjectInputStream(bis);
				
				Message testResponse = (Message) objectIn.readObject();
				
				System.out.println("Response: " + testResponse);
			}
			else
			{
				System.out.println("Something went wrong, server was not answering as expected!");
			}
		}
		catch (Exception ex)
		{
			ex.printStackTrace();
		}
	}
}

ClientHandler.java
Java:
package de.mrpixeldream.dreamcode.im.server;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;

import de.mrpixeldream.dreamcode.im.server.io.EncryptionUtility;

public class ClientHandler extends Thread {

	Socket client;
    String id;
    Scanner input;
    PrintWriter output;
    
    EncryptionUtility encryptionUtil;
    
    IMServer parent;
    
    public ClientHandler(Socket client, IMServer parent)
    {
    	this.client = client;
    	this.parent = parent;
    	
    	try
        {
                this.input = new Scanner(client.getInputStream());
                this.output = new PrintWriter(client.getOutputStream());
        }
        catch (IOException e)
        {
                e.printStackTrace();
        }
    }
    
    public void setEncryptionUtility(EncryptionUtility encUtil)
    {
    	this.encryptionUtil = encUtil;
    }
    
    @Override
    public void run()
    {
    	String msg = "";
    	
    	do
    	{
    		msg = "";
    		
    		try
            {
                msg = encryptionUtil.receiveEncrypted(client); 
                //System.out.println(msg);
    			//msg = input.nextLine();
                this.parent.getCommandHandler().handleCommand(msg, client, this);
            }
            catch (Exception e)
            {
                this.parent.log("Failed to read line from client! Logging out...", LogLevel.ERROR);
            	e.printStackTrace();
                msg = "LOGOUT";
            }
    	} while (!msg.equalsIgnoreCase("LOGOUT"));
    	
    	this.logout();
    }
    
    public void setID(String id)
    {
    	this.id = id;
    }
    
    public String getID()
    {
    	return this.id;
    }
    
    public EncryptionUtility getEncryptionUtility()
    {
    	return this.encryptionUtil;
    }
    
    public void logout()
    {
    	//this.output.println("Logging you out!");
    	this.parent.doLogout(client.getInetAddress());
    }
	
}

Hierbei ist der auskommentierte Teil im try-catch Block die alte Klartext-Kommunikation, welche ich nicht mehr nutzen möchte, sondern nun eben auf die Kommunikation über das EncryptionUtility umsteigen will.

EncryptionUtility.java
Java:
package de.mrpixeldream.dreamcode.im.server.io;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;

import org.jasypt.util.text.StrongTextEncryptor;

import de.mrpixeldream.dreamcode.im.server.thirdparty.ReadWriteAES;

public class EncryptionUtility {

	String password = "";
	StrongTextEncryptor encryptor;
	
	public EncryptionUtility(String masterPassword) {
		
		this.password = masterPassword;
		this.encryptor = new StrongTextEncryptor();
		this.encryptor.setPassword(password);
		
	}
	
	public void sendEncrypted(String message, Socket target) {
		
		try
		{
			byte[] buffer;
			
			ByteArrayOutputStream bos = new ByteArrayOutputStream();
			ObjectOutputStream objectStream = new ObjectOutputStream(bos);
			
			String[] splitMsg = message.split(" ");
			String command = splitMsg[0];
			String[] args = new String[splitMsg.length - 1];
			
			for (int i = 0; i < args.length; i++)
			{
				args[i] = splitMsg[i + 1];
			}
			
			Message messageObject = new Message(command, args);
			objectStream.writeObject(messageObject);
			
			buffer = bos.toByteArray();
			
			ReadWriteAES.encode(buffer, target.getOutputStream(), password);
			
			objectStream.close();
		}
		catch (Exception ex)
		{
			ex.printStackTrace();
		}
		
	}
	
	public String receiveEncrypted(Socket target) throws Exception {
		
		String plainCommand = "";
		
		byte[] buffer = ReadWriteAES.decode(target.getInputStream(), password);
		
		ByteArrayInputStream bis = new ByteArrayInputStream(buffer);
		ObjectInputStream objectStream = new ObjectInputStream(bis);
		
		Message messageObject = (Message) objectStream.readObject();
		
		plainCommand += messageObject.getCommand();
		
		for (String arg : messageObject.getArgs())
		{
			plainCommand += arg;
		}
		
		return plainCommand;
		
	}
	
}

Wie man sieht, ist diese Klasse dafür zuständig, Methoden zum Lesen und Schreiben von verschlüsselten Message Objekten bereitzustellen.

ReadWriteAES.java
Java:
package de.mrpixeldream.dreamcode.im.server.thirdparty;

import java.io.*;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;

import javax.crypto.*;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;

public class ReadWriteAES
{
	public static void encode( byte[] bytes, OutputStream out, String pass ) throws Exception
	{
		Cipher c = Cipher.getInstance( "AES" );
    
		SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
		KeySpec spec = new PBEKeySpec(pass.toCharArray(), "5500".getBytes(), 65536, 256);
		SecretKey tmp = factory.generateSecret(spec);
		SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");
    
		Key k = new SecretKeySpec( secret.getEncoded(), "AES" );
		//System.out.println(new String(k.getEncoded()));
		c.init( Cipher.ENCRYPT_MODE, k );

		OutputStream cos = new CipherOutputStream( out, c );
		cos.write( bytes );
		cos.flush();
		cos.close();
	}

	public static byte[] decode( InputStream is, String pass ) throws Exception
	{
	  	Cipher c = Cipher.getInstance( "AES" );
    
    	SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
    	KeySpec spec = new PBEKeySpec(pass.toCharArray(), "5500".getBytes(), 65536, 256);
    	SecretKey tmp = factory.generateSecret(spec);
    	SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");
    
    	Key k = new SecretKeySpec( secret.getEncoded(), "AES" );
    	//System.out.println(new String(k.getEncoded()));
    	c.init( Cipher.DECRYPT_MODE, k );

    	ByteArrayOutputStream bos = new ByteArrayOutputStream();
    	CipherInputStream cis = new CipherInputStream( is, c );

    	for ( int b; (b = cis.read()) != -1; )
    	{
    		bos.write( b );
    	}

    	System.out.println("miau");
    	
    	bos.flush();
    	bos.close();
    	cis.close();
    	return bos.toByteArray();
  	}

  	public static void encode(byte[] bytes, FileOutputStream out, byte[] secKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeySpecException, InvalidKeyException, IOException
	{
        Cipher c = Cipher.getInstance( "AES" );
    
        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
    	KeySpec spec = new PBEKeySpec(new String(secKey).toCharArray(), "5500".getBytes(), 65536, 256);
    	SecretKey tmp = factory.generateSecret(spec);
    	SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");
    
    	Key k = new SecretKeySpec( secret.getEncoded(), "AES" );
    	c.init( Cipher.ENCRYPT_MODE, k );

    	OutputStream cos = new CipherOutputStream( out, c );
    	cos.write( bytes );
    	cos.close();
        
	}

	public static byte[] decode(InputStream is, byte[] secKey) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IOException, InvalidKeySpecException
	{
        Cipher c = Cipher.getInstance( "AES" );
        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
        KeySpec spec = new PBEKeySpec(new String(secKey).toCharArray(), "5500".getBytes(), 65536, 256);
        SecretKey tmp = factory.generateSecret(spec);
        SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");
    
        Key k = new SecretKeySpec( secret.getEncoded(), "AES" );
        c.init( Cipher.DECRYPT_MODE, k );

        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        CipherInputStream cis = new CipherInputStream( is, c );

        for ( int b; (b = cis.read()) != -1; )
        {
            bos.write( b );
        }

        cis.close();
        return bos.toByteArray();
	}
}

Diese Klasse übernimmt das eigentliche Verschlüsseln der Streams und ich denke hier liegt auch irgendwo das Problem, auch wenn die Exception etwas anderes besagt.

Message.java
Java:
package de.mrpixeldream.dreamcode.im.server.io;

import java.io.Serializable;

public class Message implements Serializable
{
	private static final long	serialVersionUID	= 1L;
	
	String command;
	String[] args;
	
	public Message(String command, String[] args)
	{
		this.command = command;
		this.args = args;
	}
	
	public String getCommand()
	{
		return this.command;
	}
	
	public String[] getArgs()
	{
		return this.args;
	}
}

Diese Klasse enthält die Informationen, welche zwischen Server und Client übertragen werden sollen. Momentan nur ein Kommando und entsprechende Parameter, jedoch wird hier noch erweitert. Dies ist jedoch im Sachzusammenhang erst einmal unwichtig.

Wenn ich nun den Server starte, initialisiert sich dieser wie gewünscht, stellt auch die Datenbankverbindung her und tut erst einmal alles wie geplant. Anschließend starte ich den Testclient, um eben die Kommunikation zu testen. Folgende Exception wird serverseitig in der Konsole ausgegeben, sobald der Client das Broadcast Kommando abgesendet hat:
Code:
ERROR: Failed to read line from client! Logging out...
java.io.StreamCorruptedException: invalid stream header: 9CC03627
	at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:802)
	at java.io.ObjectInputStream.<init>(ObjectInputStream.java:299)
	at de.mrpixeldream.dreamcode.im.server.io.EncryptionUtility.receiveEncrypted(EncryptionUtility.java:67)
	at de.mrpixeldream.dreamcode.im.server.ClientHandler.run(ClientHandler.java:53)

Dies deutet laut meinen Recherchen darauf hin, dass ich irgendwie das Objekt clientseitig falsch in den Stream schreibe bzw. den Stream falsch öffne. Aber ich finde den Fehler einfach nicht.
Wie oben bereits kurz erwähnt könnte ich mir gut vorstellen, dass der Fehler hier irgendwo in der Verschlüsselung sitzt.

Ich wäre euch sehr dankbar, wenn ihr mir bei meinem Problem weiterhelfen könntet.
Bei Fragen zum Code stehe ich jederzeit gerne zur Verfügung, ich habe jedoch versucht, alles so genau wie möglich zu eröffnen.

Euer UNIX
 

Sen-Mithrarin

Gesperrter Benutzer
ach ... ist nur ein problem das du den gleichen fehler wie jeder anfänger machst : EINEN stream mehrfach missbrauchen ... das muss ja zu fehlern führen

Object*Stream arbeiten mit headern ... daher ist es wichtig das der ObjectInputStream direkt nach erzeugung des ObjectOutputStream erstellt wird

wenn man EINEN stream hat über den man mehrere verschiedene daten schicken muss > Data*Stream nutzen ! und nicht immer wieder "new BLA*Stream(Socket.get*Stream())" ... damit versaut man header-informationen
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
B FTP commons net verschlüsselte verbindung Netzwerkprogrammierung 11
G Verschlüsselte Strings über Netzwerk verschicken Netzwerkprogrammierung 19
E HTTPS Debuggen (verschlüsselte Daten anzeigen)? Netzwerkprogrammierung 12
ExceptionOfExpectation Server/Client-Kommunikation Netzwerkprogrammierung 34
G Socket Socket Kommunikation Netzwerkprogrammierung 1
R Kommunikation zwischen Shell und Putty Netzwerkprogrammierung 5
temi (Netzwerk-) Kommunikation zwischen Anwendungen. Wie? Netzwerkprogrammierung 5
T Client zu Client Kommunikation Netzwerkprogrammierung 2
K Socket Nur bestimmte Zeichen als Kommunikation zulassen Netzwerkprogrammierung 1
I Client/Server Kommunikation bei einem Spiel Netzwerkprogrammierung 4
H Android - PC kommunikation Netzwerkprogrammierung 3
S Server Kommunikation Netzwerkprogrammierung 1
brainless Client Server Kommunikation verschlüsseln Netzwerkprogrammierung 13
T Socket Server/Client Kommunikation Netzwerkprogrammierung 8
I Socket Kommunikation C / Java Netzwerkprogrammierung 2
M Kommunikation übers Internet Netzwerkprogrammierung 9
P MIME-TYPE Erklaerung, Kommunikation zwischen Client und Server Netzwerkprogrammierung 3
J Sichere Kommunikation bei Server Client Netzwerkprogrammierung 3
Shams Anfängerfrage zu Server-Socket-Kommunikation Netzwerkprogrammierung 2
S Socket Kommunikation über Internet Netzwerkprogrammierung 1
I Interne Computer Kommunikation Netzwerkprogrammierung 6
M allgemeine Frage über Server-Client-Kommunikation Netzwerkprogrammierung 5
L Ratschlag zur Umsetzung einer client-server-Kommunikation Netzwerkprogrammierung 6
R Server zu Client Kommunikation Netzwerkprogrammierung 11
V Socket UDP Server/Client Kommunikation sehr langsam Netzwerkprogrammierung 2
Y HTTP Google Reader API Kommunikation Netzwerkprogrammierung 3
C Socket Kommunikation mit SMTP-Server Netzwerkprogrammierung 4
J Kommunikation von Webanwendungen (auf Tomcat Server) untereinander Netzwerkprogrammierung 8
H Kommunikation Netzwerkprogrammierung 8
F Socket Server/Client Kommunikation Netzwerkprogrammierung 4
X Problem mit Server-Client-Kommunikation Netzwerkprogrammierung 14
E Zeitgleiche Kommunikation, mögliche Ansätze Netzwerkprogrammierung 17
1 Java to Android TCP Kommunikation Netzwerkprogrammierung 2
O php - applet Kommunikation Netzwerkprogrammierung 9
D HTTP Java HTTP Kommunikation Netzwerkprogrammierung 9
1 SSH-Kommunikation - Ende eines Streams nicht erkenntlich Netzwerkprogrammierung 2
R Kommunikation TCP + UDP Netzwerkprogrammierung 3
S RMI RMI-Applet kommunikation funktioniert nicht Netzwerkprogrammierung 8
1 Kommunikation mit externem Programm über TCP Netzwerkprogrammierung 2
D Server-Client (Web) Kommunikation Netzwerkprogrammierung 9
E Client-Server-Kommunikation Netzwerkprogrammierung 13
C HTTP Studienarbeit Kommunikation via HTTP mit POST zwischen Server und Client Netzwerkprogrammierung 7
DamienX Socket Asnchrone Kommunikation Netzwerkprogrammierung 5
Raidri Rückwertige RMI Kommunikation Netzwerkprogrammierung 6
S TCP/IP-Kommunikation ist zu langsam Netzwerkprogrammierung 13
M Kommunikation zwischen ServerSocket und Socket Netzwerkprogrammierung 2
G Datagram-Sockets für UDP-Kommunikation Netzwerkprogrammierung 2
G java asynchrone kommunikation Netzwerkprogrammierung 8
B Rmi Kommunikation Server zu mehreren Clients? Netzwerkprogrammierung 3
G Problem mit Client-Server Kommunikation Netzwerkprogrammierung 4
N Servlet-RMI Kommunikation Netzwerkprogrammierung 8
G Objecte für Kommunikation nutzen Netzwerkprogrammierung 2
L http kommunikation mit und ohne multipart Netzwerkprogrammierung 4
D Einfache Applet-Servlet-Kommunikation Netzwerkprogrammierung 5
G unvollständige Daten: Http Client-Server-Kommunikation Netzwerkprogrammierung 2
RaoulDuke RMI Kommunikation Java <-> Perl Netzwerkprogrammierung 7
M Servlet - Applet Kommunikation Netzwerkprogrammierung 3
S Kommunikation zweier Java-Programme Netzwerkprogrammierung 6
J client/server kommunikation Netzwerkprogrammierung 3
T Kommunikation auf Byte-Ebene zw. C und Java via Socket Netzwerkprogrammierung 12
M Client-Kommunikation ohne Server Netzwerkprogrammierung 7
S Kommunikation Fortran <-> Java auf Client-Server-Archi Netzwerkprogrammierung 2
J Kommunikation zw. Server und mehreren Clints haut nicht hin Netzwerkprogrammierung 2
K Socket Kommunikation Netzwerkprogrammierung 3
K Applet - Servlet Kommunikation ohne Sockets Netzwerkprogrammierung 5
R applet servlet kommunikation Netzwerkprogrammierung 2
G JINI über RMI // Client-Server Kommunikation Netzwerkprogrammierung 4
D Kommunikation zwischen mehreren Servlets??? Netzwerkprogrammierung 3
K Threads/Server/telnet Fehler Netzwerkprogrammierung 2
X Netty TLS Authentifizierung Fehler Netzwerkprogrammierung 1
OnDemand API Aufruf besser steuern, wie Fehler vermeiden Netzwerkprogrammierung 20
V Ich finde den Fehler nicht... Netzwerkprogrammierung 2
A sporadischer Fehler beim Schreiben auf NAS Netzwerkprogrammierung 2
K Socket Netty Client wirft Fehler! Netzwerkprogrammierung 3
F HTTP Website parsen Fehler 403 Netzwerkprogrammierung 2
M Wo ist mein Fehler ? o: Netzwerkprogrammierung 4
D Komischer Fehler Readline() Netzwerkprogrammierung 7
CookieSoft Fehler bei Socket Netzwerkprogrammierung 4
B RMI & Mysql -> Fehler bei der Compilierung Netzwerkprogrammierung 4
C Fehler bei PDF-Download Netzwerkprogrammierung 5
M ActiveMQ Anfänger-Fehler Netzwerkprogrammierung 3
N Socket Fehler bei Streams Netzwerkprogrammierung 2
F Socket ImageIcon über Socket --> Fehler Netzwerkprogrammierung 14
M chat als applet umgeschrieben - unbekannter fehler :( Netzwerkprogrammierung 2
B Socket Daten empfangen funktioniert nicht richtig - wo liegt der Fehler? Netzwerkprogrammierung 7
L NullPointerException...finde den Fehler nicht Netzwerkprogrammierung 10
E einfache Frage: wie Fehler untersuchen mit Tomcat Netzwerkprogrammierung 5
R Fehler bei RMI in Verbidung mit JDBC Netzwerkprogrammierung 6
L RMI Programm beendet ohne Fehler sofort nach Start (Windows 2000) Netzwerkprogrammierung 7
R Server - Client - Fehler? Netzwerkprogrammierung 3
M SOAP Messaging Fehler Netzwerkprogrammierung 10
J RMI Fehler beim Proxy Netzwerkprogrammierung 2
B Fehler 401 bei http GET Netzwerkprogrammierung 2
H RMI Fehler: access denied Netzwerkprogrammierung 10
J Vom BufferedReader lesen -> hängt ohne Fehler,ohne Except Netzwerkprogrammierung 2
C irc client: Fehler 451 Netzwerkprogrammierung 12
G Heimnetzwerkchatprogramm: Fehler im Code Netzwerkprogrammierung 11

Ähnliche Java Themen

Neue Themen


Oben