Objekt in Bytestream umwandeln

Jackcarver12

Mitglied
Hallo,
im Rahmen einer gemeinsamen Projektarbeit (Chat) habe ich die Aufgabe bekommen ein Objekt bzw. eine Nachricht zu verschlüsseln und wieder zu entschlüsseln.
Dies will ich mit dem RSA-Verfahren umsetzen (asynchrone Verschlüsselung).

Dafür wird mir in einer Funktion der Klasse Crypt (Klasse die alle Methoden für die Verschlüsselung enthalten soll) ein Objekt der eigens hierfür erstellte Klasse "Nachricht" übergeben. Eine Instanz der Klasse Nachricht würde normalerweise einen Nachrichten Objekt String erzeugen. Nun wurden Subklassen von der Klasse Nachricht erstellt, welche auch Bilder o.ä. enthalten können.

Mir wird das dementsprechende Objekt (welches zu senden wäre) in einer Funktion übergeben. (Übergeben wird entweder ein Nachrichtenobjekt oder ein ObjectOutputStream je nachdem wie ich hier beraten werde) .
Ziel wäre es also dementsprechend folgendes umzusetzen:

Mein Objekt/ObjectOutputStream soll in ein byte[] Typ umgewandelt werden, sodass ich die RSA Verschlüsselung darauf anwenden kann. Ich wüsste nicht wie ich sonst die asynchrone Verschlüsselung anwenden soll.

Über jeglichen Input/Ratschläge/Anweisungen freue ich mich sehr und werde natürlich versuchen Sie in meinen Teil des Projekt einzuarbeiten.

Code:
public class Crypter
{
    KeyPair key=null;
    PublicKey pk=null;

    public void getOutputStream(Nachricht msg) //oder ObjectOutputStream
    {
          ByteArrayOutputStream bos = new ByteArrayOutputStream();
          ObjectOutputStream oos = new ObjectOutputStream(bos);
          oos.writeObject(msg);
          byte [] bstream = bos.toByteArray();
          return bstream;
    }
   
    public void gen()
    {
       
        final KeyPairGenerator keygen= KeyPairGenerator.getInstance("RSA");//keygenerator generieren
        keygen.initialize(1024); //damit es nicht so langsam ist 2^x
        final KeyPair key= keygen.generateKeyPair();    //keypair generieren also public und private?
       
    }
   
    public static byte[] encrypt(ObjectOutputStream oos, PublicKey pk)
    {
       
        //ObjectOutputStream wird übernommen und die in ein byteaarry
        Cipher cipher=null;
        try
        {
            cipher=Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, pk);

        }catch(NoSuchAlgorithmException e1)
        {
            e1.printStackTrace();
        }
        catch(NoSuchPaddingException e2)
        {
            e2.printStackTrace();
        }
        try
        {
           
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ObjectOutputStream objectStream = new ObjectOutputStream(bos);
           
            byte[] chiffrat=cipher.doFinal(oos.getBytes()); //hier sollte der OutputStream reinkommen/oder der String?
            return chiffrat;
           
        }catch(IllegalAccessException e3)
        {
            e3.printStackTrace();
        }
       
    }
   
    public static String decrypt(byte[] chiffrat, SecretKey sk)
    {
        byte[] dec= null;
        Cipher cipher=null;
        try
        {
         cipher=Cipher.getInstance("RSA");
        cipher.init(cipher.DECRYPT_MODE, sk);
        }catch(InvalidKeyException e4)
        {
            e4.printStackTrace();
        }
        try
        {
        dec= cipher.doFinal(chiffrat);
       
        }catch(IllegalBlockSizeException e5)
        {
            e5.printStackTrace();
        }
        return new String(dec);
       
    }
    public void main (String [] args)
    {
        gen();
        byte[] enc=encrypt("hallo Welt",key.getPublic());
        System.out.println(enc);
       
    }
}

Hier handelt es sich eher um eine kleine Zusammenschrift was ich alles benötigen könnte. Ich habe bereits etwas damit experimentiert, konnte aber noch nichts nennenswertes erreichen.

PS: Ich will an dieser Stelle betonen, dass ich mir keine Lösung der allgemeinen Problematik erhoffe, sondern eher eine Anleitung. Schließlich sollte ich am Ende den Sachverhalt verstanden haben, was momentan noch nicht der Fall ist. Die allgemeine RSA-Verschlüsselung anzuwenden sollte nicht das größte Problem sein. Ich habe das Problem, dass ich nicht genau weiss wo was von dem Code hingehört.

Ich hoffe Ich konnte mein Problem zumindest ansatzweise verdeutlichen.

Vielen Dank für eure Hilfe,
jackcarver12
 
X

Xyz1

Gast
Dein Beitrag ist nicht ganz leicht zu verstehen, aber allgemein kannst du ein (fast beliebiges) Objekt per OOS in bytes zerlegen, diese verschlüsseln, senden, empfangen, entschlüsseln und zurückcasten.
 
X

Xyz1

Gast
Hier mal eine Minimalbeispiel von dieser Seite: https://blog.axxg.de/java-aes-verschluesselung-mit-beispiel/

Java:
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.MessageDigest;
import java.util.Arrays;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

public class T {
	public static void main(String[] args) throws InterruptedException {
		new Thread(new Server()).start();
		Thread.sleep(1000);
		new Thread(new Client()).start();
	}
}

class Nachricht implements Serializable {
	private static final long serialVersionUID = -400L;
	
	// HIER DEINE ATTRIBUTE...
	public int i;
	public double d;
	public String s;
	// HIER DEINE ATTRIBUTE.

	@Override
	public String toString() {
		return String.format("Nachricht [i=%s, d=%s, s=%s]", i, d, s);
	}
}

class VerNachricht implements Serializable {
	private static final long serialVersionUID = -300L;
	public byte[] geheim;
}

class Dealer {
	VerNachricht getVerNachricht(Nachricht n) throws Exception {
		// Das Passwort bzw der Schluesseltext
		String keyStr = "geheim";
		// byte-Array erzeugen
		byte[] key = (keyStr).getBytes("UTF-8");
		// aus dem Array einen Hash-Wert erzeugen mit MD5 oder SHA
		MessageDigest sha = MessageDigest.getInstance("SHA-256");
		key = sha.digest(key);
		// nur die ersten 128 bit nutzen
		key = Arrays.copyOf(key, 16);
		// der fertige Schluessel
		SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");

		ByteArrayOutputStream stream = new ByteArrayOutputStream();
		try (ObjectOutputStream o = new ObjectOutputStream(stream)) {
			o.writeObject(n);
		}
		byte[] b = stream.toByteArray();

		// Verschluesseln
		Cipher cipher = Cipher.getInstance("AES");
		cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
		byte[] encrypted = cipher.doFinal(b);

		VerNachricht verNachricht = new VerNachricht();
		verNachricht.geheim = encrypted;
		return verNachricht;
	}

	Nachricht getNachricht(VerNachricht n) throws Exception {
		// Das Passwort bzw der Schluesseltext
		String keyStr = "geheim";
		// byte-Array erzeugen
		byte[] key = (keyStr).getBytes("UTF-8");
		// aus dem Array einen Hash-Wert erzeugen mit MD5 oder SHA
		MessageDigest sha = MessageDigest.getInstance("SHA-256");
		key = sha.digest(key);
		// nur die ersten 128 bit nutzen
		key = Arrays.copyOf(key, 16);
		// der fertige Schluessel
		SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");

		// Entschluesseln
		Cipher cipher2 = Cipher.getInstance("AES");
		cipher2.init(Cipher.DECRYPT_MODE, secretKeySpec);
		byte[] cipherData2 = cipher2.doFinal(n.geheim);

		Nachricht nachricht = null;
		ByteArrayInputStream stream = new ByteArrayInputStream(cipherData2);
		try (ObjectInputStream i = new ObjectInputStream(stream)) {
			Object o = i.readObject();
			if (o != null && o instanceof Nachricht) {
				nachricht = (Nachricht) o;
			}
		}
		return nachricht;
	}
}

class Server implements Runnable {
	@Override
	public void run() {
		try (ServerSocket ss = new ServerSocket(1235)) {
			while (true) {
				try {
					Socket accept = ss.accept();
					try (ObjectInputStream stream = new ObjectInputStream(accept.getInputStream())) {
						System.out.println("empfange");
						Object o = stream.readObject();
						if (o != null && o instanceof VerNachricht) {
							Nachricht n = new Dealer().getNachricht((VerNachricht) o);
							System.out.println(n);
							// ...
						}
					}
				} catch (Exception e1) {
					e1.printStackTrace();
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

class Client implements Runnable {
	@Override
	public void run() {
		try {
			Nachricht n = new Nachricht();
			n.i = 12;
			n.d = 34;
			n.s = "super geheimer Text";

			try (Socket socket = new Socket("localhost", 1235);
					ObjectOutputStream stream = new ObjectOutputStream(socket.getOutputStream())) {
				System.out.println("sende");
				stream.writeObject(new Dealer().getVerNachricht(n));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}


Das Schlimme ist ja dass das sogar sicher ist. :D
 

Jackcarver12

Mitglied
Hallo Tobias,
Danke für deine Antwort!
Ich würde dein Angebot gerne Annehmen und dir direkt schreiben, aber ich denke ich bin wissenstechnisch noch nicht so weit. Beispielsweise wollte ich mit RSA verschlüsseln. Bei dir sehe ich aber unter anderem öfter MessageDigest und AES. Das sagt mir noch relativ wenig.
Ich bin nun etwas vorangekommen. Zumindest hoffe ich das.
Java:
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;

public class Crypt
{
    KeyPair key=null;
    PublicKey pk=null;

   
    public KeyPair getKey()
    {
        return key;
    }

    public void setKey(KeyPair key)
    {
        this.key = key;
    }

    public PublicKey getPk()
    {
        return pk;
    }

    public void setPk(PublicKey pk)
    {
        this.pk = pk;
    }

   
   
   
    //Generiert die Schüssel bereitet alles für die Verschlüsselung vor
    public void gen()
    {
       
        KeyPairGenerator keygen=null;
        try
        {
            keygen = KeyPairGenerator.getInstance("RSA");
        } catch (NoSuchAlgorithmException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }//keygenerator generieren
       
        keygen.initialize(1024); // 2^x
        final KeyPair key= keygen.generateKeyPair();    //keypair generieren also public und private?    
    }
   
   
   
    //Wandelt das Nachrichtenobjekt in ein byte[] um und returnt das byte[]
    public byte[] getByteStream(Nachricht msg)
    {
        gen();
          ByteArrayOutputStream bos = new ByteArrayOutputStream();
          ObjectOutputStream oos=null;
        try
        {
            oos = new ObjectOutputStream(bos);
        } catch (IOException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
          try
        {
            oos.writeObject(msg); //Objekt in das byte[] schreiben
        } catch (IOException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
          byte [] bstream = bos.toByteArray();
         
          return bstream;
   
    }
   
    //verschlüsseln des byte[]
    public byte[] vByteArray(byte[] ostream, PublicKey pk)
    {
        Cipher cipher=null;
        byte[] chiffrat=null;
       
        try
        {
            cipher=Cipher.getInstance("RSA");
            try
            {
                cipher.init(Cipher.ENCRYPT_MODE, pk);
            } catch (InvalidKeyException e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }catch(NoSuchAlgorithmException e1)
        {
            e1.printStackTrace();
        }
        catch(NoSuchPaddingException e2)
        {
            e2.printStackTrace();
        }
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try
        {
            ObjectOutputStream objectStream = new ObjectOutputStream(bos);
        } catch (IOException e1)
        {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
       
        try
        {
            chiffrat=cipher.doFinal(ostream);
        } catch (IllegalBlockSizeException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (BadPaddingException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } //ist das so korrekt?
        return chiffrat; //verschlüsselt mit RSA
    }
   
    public static Nachricht decrypt(byte[] chiffrat, SecretKey sk)
    {
       
        byte[] dec= null;
        Cipher cipher=null;
       
       
        try //er will dass ich doppelt trycatche warum?
        {
         try
        {
            cipher=Cipher.getInstance("RSA");
        } catch (NoSuchAlgorithmException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchPaddingException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        cipher.init(cipher.DECRYPT_MODE, sk);
        }catch(InvalidKeyException e4)
        {
            e4.printStackTrace();
        }
       
       
        try //warum muss ich hier doppel und dreifach trycatchen? das ist doch quatsch so oder nicht?
        {
           
        try
        {
            dec= cipher.doFinal(chiffrat);
           
        } catch (BadPaddingException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
       
        }catch(IllegalBlockSizeException e5)
        {
            e5.printStackTrace();
        }
        return new Nachricht(dec); //hier muss nun noch aus dem chiffrat wieder von byte[] zu Nachricht umgewandelt werden
    }

Einer meiner wunden Punkte ist auch das Umwandeln von byte[] zu Nachrichtenobjekt wie man in der letzen Zeile meines Codes vielleicht erkennt. Das wird bei mir noch angestrichen.
Ich hoffe damit lässt sich besser verstehen wo die Reise hingeht.
Dein Code hat mir geholfen zu verstehen wo ich ansetzen muss!
LG
Jackcarver
 
Zuletzt bearbeitet:
X

Xyz1

Gast
Ach so Sorry, RSA hatte ich erst nicht gelesen. Das ist auch besser denn das AES oben nutzt nur 128bit. :(

Freue mich wenn ich helfen konnte. ;)
 

mihe7

Top Contributor
habe ich die Aufgabe bekommen ein Objekt bzw. eine Nachricht zu verschlüsseln und wieder zu entschlüsseln.
Zunächst mal sollte man sich klar machen, dass man ein Objekt nicht verschlüsseln/entschlüsseln kann. Was man da verschlüsselt/entschlüsselt, ist die serialisierte Form des Objekts.

Mit dieser Erkenntnis kann man sich überlegen, dass es am Ende vollkommen egal ist, was man verschlüsseln/entschlüsseln möchte: am Ende läuft es immer auf Bits und Bytes bzw. Ströme davon hinaus.

Dann kommt hinzu, dass Ver- und Entschlüsseln völlig verschiedene Dinge sind, die man dem entsprechend auf zwei Klassen aufteilen kann: Encrypt und Decrypt. Dann wird der Code schon mal übersichtlicher.

Die Setter/Getter brauchen diese Klassen nicht, den betreffenden Schlüssel kannst Du im Konstruktor mitgeben.

Das Ganze spinnt man noch ein Weilchen weiter und kommt dann auf eine Lösung, die in großen Teilen mit CipherOutputStream und CipherInputStream schon existiert...
 
X

Xyz1

Gast
Das Ganze spinnt man noch ein Weilchen weiter und kommt dann auf eine Lösung, die in großen Teilen mit CipherOutputStream und CipherInputStream schon existiert
Ja oder die https://docs.oracle.com/javase/9/security/java-secure-socket-extension-jsse-reference-guide.htm verwendenden, aber ich wollte das einmal manuell vormachen...

Zu bedenken ist auch, dass bekannt sein könnte, dass eine verschlüsselte Nachricht gesendet wurde, aber eben nicht deren Inhalt...
 

Jackcarver12

Mitglied
Zunächst mal sollte man sich klar machen, dass man ein Objekt nicht verschlüsseln/entschlüsseln kann. Was man da verschlüsselt/entschlüsselt, ist die serialisierte Form des Objekts.

Mit dieser Erkenntnis kann man sich überlegen, dass es am Ende vollkommen egal ist, was man verschlüsseln/entschlüsseln möchte: am Ende läuft es immer auf Bits und Bytes bzw. Ströme davon hinaus.

Dann kommt hinzu, dass Ver- und Entschlüsseln völlig verschiedene Dinge sind, die man dem entsprechend auf zwei Klassen aufteilen kann: Encrypt und Decrypt. Dann wird der Code schon mal übersichtlicher.

Die Setter/Getter brauchen diese Klassen nicht, den betreffenden Schlüssel kannst Du im Konstruktor mitgeben.

Das Ganze spinnt man noch ein Weilchen weiter und kommt dann auf eine Lösung, die in großen Teilen mit CipherOutputStream und CipherInputStream schon existiert...

Dass ich das eigentliche Objekt nicht verschlüsseln kann, ist mir durchaus bewusst. Daher habe ich meinen Code vorangestellt. Dort kann man hoffentlich entnehmen, dass ich versuche das Ganze in ein Byte[] umzuwandeln.

Das aufteilen von Ver- und Entschlüsseln auf zwei Klassen kann ich noch nicht verstehen. Warum sollte ich dafür nicht jeweils eine Funktion machen. Könntest du mir das vielleicht etwas näher erläutern?

Ich hatte ja meinen Code vorangestellt.
Das ist momentan mein Plan:
Ablauf beim Sender (Client)
1) cryptobjekt erstellen
2) byte[] ostream=crypt.getByteStream(Nachricht msg); //objekt in stream schreiben;umwandeln von objektstream zu byte[];
3) byte[] vostream=crypt.encrypt(byte[] ostream, PublicKey pk); // ostream verschlüsseln; mit RSA
vostream=verschlüsselterbytestream (vostream=chiffrat im Code)
Ablauf beim Empfänger: (Im Proxy oder im Client)
1)cryptobjekt erstellen
2)byte[] eostream=crypt.decript(byte[] vostream,SecretKey sk); //entschlüsseln
3)eostream in Nachrichten Objekt umwandeln //ich weiss nicht wie ich es umwandeln soll
Hier hänge ich und kann mein Programm deshalb auch nicht testen.

@Tobias-nrw : Ja das dachte ich mir bereits! Trotzdem mega nett. Auch der Link enthält viel wertvolle Theorie. Danke dafür!
Was mein Codeproblem angeht und die Tatsache, dass ich ihn vorab nicht testen kann... bin ich leider nicht weitergekommen
ich muss es irgendwie hinbekommen das byte[] in das Nachrichtenobjekt von zuvor wieder zu casten.


LG
 

mihe7

Top Contributor
Dass ich das eigentliche Objekt nicht verschlüsseln kann, ist mir durchaus bewusst. Daher habe ich meinen Code vorangestellt. Dort kann man hoffentlich entnehmen, dass ich versuche das Ganze in ein Byte[] umzuwandeln.
Anscheinend ist mein Wink mit dem Zaunpfahl nicht angekommen. Deinen Code habe ich mir natürlich angesehen.

Deine Klasse muss es nicht interessieren, was da verschickt wird. Alles, was Du tun musst, ist einen CipherOutputStream bzw. einen CipherInputStream aufzusetzen, um einen beliebigen OutputStream ver- bzw. einen InputStream entschlüsseln zu können. Dabei kann es sich um Objektstreams oder Bytestreams handeln, völlig egal. Wenn Du spezielle Klassen behandeln willst, könntest Du einen Decorator für die Streams basteln.

Damit erübrigen sich zunächst einmal Probleme wie:
bin ich leider nicht weitergekommen
ich muss es irgendwie hinbekommen das byte[] in das Nachrichtenobjekt von zuvor wieder zu casten.
Man kann kein byte[] in ein x-beliebiges Objekt casten. Du musst den gleichen Weg gehen, wie beim Verschlüsseln - nur eben andersrum. In Deinem Fall müsstest Du also erstmal die Bytes lesen in ein Array lesen, und dann mittels ObjectInputStream über den Umweg via ByteArrayInputStream aus dem Array das betreffende Objekt herauslesen.
 

mihe7

Top Contributor
Das kommt darauf an. Ich hätte es so verstanden, dass eine Ende-zu-Ende-Verschlüsselung für die Nachrichten gebaut werden soll. Dann wäre das kein "oder", sondern ein "und". Für Daten, die der Server für das Routing der Message braucht, darf natürlich nur der Transport abgesichert sein. Aber der Inhalt der Nachricht geht den Betreiber nichts an.
 

Jackcarver12

Mitglied
Das kommt darauf an. Ich hätte es so verstanden, dass eine Ende-zu-Ende-Verschlüsselung für die Nachrichten gebaut werden soll. Dann wäre das kein "oder", sondern ein "und". Für Daten, die der Server für das Routing der Message braucht, darf natürlich nur der Transport abgesichert sein. Aber der Inhalt der Nachricht geht den Betreiber nichts an.

Hey Mihe!
Danke für die schnelle Antwort!
Doch doch ich habe schon verstanden, dass die CipherOutputStreams scheinbar essentiell für das Projekt sind. Wenn ich das Thema allerdings online recherchiere (RSA Verschlüsselung allgemein) finde ich wenig bis garnichts.

Wäre es also nicht am besten folgendes zu versuchen:

Ich habe bereits einen code mit dem ich strings verschlüsseln kann:
Java:
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;

import java.security.Key;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;

public class EncryptionTest {

 /**
 * Zwischengespeichertes Schluesselpaar
 */
 private static KeyPair keyPair;

 /**
 * Erzeugt ein RSA Schluesselpaar
 *
 * @return RSA Schluesselpaar
 * @throws Exception
 */
 public static KeyPair getKeyPair() throws Exception {
 if (keyPair == null) {
 KeyPairGenerator kpg;
 try {
 kpg = KeyPairGenerator.getInstance("RSA");
 kpg.initialize(2048);
 keyPair = kpg.generateKeyPair();
 } catch (NoSuchAlgorithmException e) {
 throw new Exception(
 "Fehler beim Erzeugen des Schluesselpaars: "
 + e.getMessage());
 }
 }

 return keyPair;
 }

 /**
 * Wrapped einen OutputStream in einen verschlüsselnden CipherOutputStream
 *
 * @param os
 * OutputStream
 * @return verschlüsselter OutputStream
 * @throws Exception
 */
 public static OutputStream encryptOutputStream(OutputStream os)
 throws Exception {
 try {
 // temporaeren AES Key erzeugen
 KeyGenerator keygen = KeyGenerator.getInstance("AES");
 SecureRandom random = new SecureRandom();
 keygen.init(random);
 SecretKey key = keygen.generateKey();

 // mit RSA verschluesseln und an Empfaenger senden
 Cipher cipher = Cipher.getInstance("RSA");
 cipher.init(Cipher.WRAP_MODE, getKeyPair().getPublic());
 byte[] encryptedAesKey = cipher.wrap(key);
 os.write(encryptedAesKey);

 // eigentliche Nachricht mit AES verschluesseln
 cipher = Cipher.getInstance("AES");
 cipher.init(Cipher.ENCRYPT_MODE, key);
 os = new CipherOutputStream(os, cipher);
 } catch (Exception e) {
 throw new Exception("Fehler beim Verschluesseln: " + e.getMessage());
 }

 return os;
 }

 /**
 * Liest den Inhalt einer Datei aus.
 *
 * @param file
 * Dateiname
 * @return Dateiinhalt (erste Zeile)
 * @throws Exception
 */
 public static String readFile(String file) throws Exception {
 InputStream is = new FileInputStream(file);
 InputStreamReader isr = new InputStreamReader(is);
 BufferedReader isrb = new BufferedReader(isr);
 return isrb.readLine();
 }

 /**
 * Wrapped einen InputStream in einen entschlüsselnden CipherInputStream
 *
 * @param is
 * InputStream
 * @return entschlüsselnder Inputstream
 * @throws Exception
 */
 public static InputStream decryptInputStream(InputStream is)
 throws Exception {
 try {
 // AES Key lesen
 byte[] wrappedKey = new byte[256];
 is.read(wrappedKey, 0, 256);

 // AES Key mit RSA entschluesseln
 Cipher cipher = Cipher.getInstance("RSA");
 cipher.init(Cipher.UNWRAP_MODE, getKeyPair().getPrivate());
 Key key = cipher.unwrap(wrappedKey, "AES", Cipher.SECRET_KEY);

 // Daten mit AES entschluesseln
 cipher = Cipher.getInstance("AES");
 cipher.init(Cipher.DECRYPT_MODE, key);

 is = new CipherInputStream(is, cipher);
 } catch (Exception e) {
 throw new Exception("Fehler beim Entschluesseln: " + e.getMessage());
 }

 return is;
 }

 /**
 * Beispiel für Verschlüsselung mit CipherInputStream und CipherOutputStream
 *
 * @param args
 */
 public static void main(String... args) {
 try {

 String file = "c:/tmp/test.txt";
 String plain = "test bla bla";
 System.out.println("Klartext: " + plain);

 // verschlüsseln
 OutputStream os = new FileOutputStream(file);
 os = encryptOutputStream(os);
 OutputStreamWriter osw = new OutputStreamWriter(os);
 osw.write(plain);
 osw.close();

 // verschlüsselten Text ausgeben
 String secret = readFile(file);
 System.out.println("verschluesselter Text: " + secret);

 // entschlüsseln
 InputStream is = new FileInputStream(file);
 is = decryptInputStream(is);
 InputStreamReader isr = new InputStreamReader(is);
 BufferedReader isrb = new BufferedReader(isr);
 String decryptedPlain = isrb.readLine();
 isrb.close();
 System.out.println("entschluesselter Text: " + decryptedPlain);

 } catch (Exception e) {
 System.err.println(e.getMessage());
 }

 }

}

Ich will es nun einfach so umschreiben, dass ich ein Objekt darin verarbeiten kann. Dazu sollte es nur nötig sein das Objekt zu serialisieren. Einen Stream zur Datei herzustellen und diesen Stream zu verschlüsseln (RSA). Anschließend wird dieser verschüsselte Stream dann wieder entschlüsselt und wieder encrypted. Liege ich mit diesem Ansatz richtig?

LG
 

mihe7

Top Contributor
Ich will es nun einfach so umschreiben, dass ich ein Objekt darin verarbeiten kann. Dazu sollte es nur nötig sein das Objekt zu serialisieren. Einen Stream zur Datei herzustellen und diesen Stream zu verschlüsseln (RSA). Anschließend wird dieser verschüsselte Stream dann wieder entschlüsselt und wieder encrypted. Liege ich mit diesem Ansatz richtig?
Genau, statt dem OutputStreamWriter kannst Du einen ObjectOutputStream verwenden. Analog fürs entschlüsseln ObjectInputStream.
 
X

Xyz1

Gast
Das sollte jetzt aber wirklich, sehr sicher sein ;) Abgeschaut habe ich das von hier: https://howtodoinjava.com/security/aes-256-encryption-decryption/ .
Java:
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.spec.KeySpec;
import javax.crypto.*;
import javax.crypto.spec.*;

public class T {
	public static void main(String[] args) throws InterruptedException {
		new Thread(new Server()).start();
		Thread.sleep(1000);
		new Thread(new Client()).start();
	}
}

class GeheimeNachricht implements Serializable {
	private static final long serialVersionUID = -400L;

	// HIER DEINE ATTRIBUTE...
	public int i;
	public double d;
	public String s;
	// HIER DEINE ATTRIBUTE.

	@Override
	public String toString() {
		return String.format("Nachricht [i=%s, d=%s, s=%s]", i, d, s);
	}
}

class Dealer {
	private static String secretKey = "megaa geheim!1!!";
	private static String salt = "ssshhhhhhhhhhh!1!!";

	byte[] getNachricht(GeheimeNachricht n) throws Exception {
		byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
		IvParameterSpec ivspec = new IvParameterSpec(iv);

		SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
		KeySpec spec = new PBEKeySpec(secretKey.toCharArray(), salt.getBytes(), 65536, 256);
		SecretKey tmp = factory.generateSecret(spec);
		SecretKeySpec secretKey = new SecretKeySpec(tmp.getEncoded(), "AES");

		Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
		cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivspec);

		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		try (ObjectOutputStream oos = new ObjectOutputStream(bos)) {
			oos.writeObject(n);
		}

		return cipher.doFinal(bos.toByteArray());
	}

	GeheimeNachricht getNachricht(byte[] n) throws Exception {
		byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
		IvParameterSpec ivspec = new IvParameterSpec(iv);

		SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
		KeySpec spec = new PBEKeySpec(secretKey.toCharArray(), salt.getBytes(), 65536, 256);
		SecretKey tmp = factory.generateSecret(spec);
		SecretKeySpec secretKey = new SecretKeySpec(tmp.getEncoded(), "AES");

		Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
		cipher.init(Cipher.DECRYPT_MODE, secretKey, ivspec);

		ByteArrayInputStream bis = new ByteArrayInputStream(cipher.doFinal(n));
		try (ObjectInputStream ois = new ObjectInputStream(bis)) {
			return (GeheimeNachricht) ois.readObject();
		}
	}
}

class Server implements Runnable {
	@Override
	public void run() {
		try (ServerSocket ss = new ServerSocket(1235)) {
			while (true) {
				try (Socket accept = ss.accept();
						ObjectInputStream stream = new ObjectInputStream(accept.getInputStream())) {
					System.out.println("empfange");
					GeheimeNachricht n = new Dealer().getNachricht(stream.readAllBytes());
					System.out.println(n);
					// ...
				} catch (Exception e1) {
					e1.printStackTrace();
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

class Client implements Runnable {
	@Override
	public void run() {
		GeheimeNachricht n = new GeheimeNachricht();
		n.i = 12;
		n.d = 34;
		n.s = "super geheimer Text";

		try (Socket socket = new Socket("localhost", 1235);
				ObjectOutputStream stream = new ObjectOutputStream(socket.getOutputStream())) {
			System.out.println("sende");
			stream.write(new Dealer().getNachricht(n));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}


/e Der ServerSocket sollte i-wann geschlossen werden und wie mihe7 es gesagt hat, secretKey im Konstruktor hinzufügen...
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
N Lwjgl 3d Objekt wird schmaler, wenn es sich dreht Allgemeine Java-Themen 0
B Ein Objekt einer Klasse mehreren anderen Klassen zur Verfügung stellen? Allgemeine Java-Themen 6
T Objekt Array Aufgabe mit Busdatenbank Allgemeine Java-Themen 2
Maxi-JOO Klassen Dummy Objekt in anderen Constructor übergeben Allgemeine Java-Themen 5
el_niiinho13 Objekt auf der Konsole ausgeben lassen Allgemeine Java-Themen 8
d.lumpi Aus Einer Klasse auf ein Objekt einer anderen Klasse Zugreifen Allgemeine Java-Themen 1
A Objekt aus anderen Objekten machen Allgemeine Java-Themen 8
SaftigMelo In einem Winkel Objekt bewegen Allgemeine Java-Themen 2
E Datentypen Wie kann ich die Längen der unterschiedlichen Ebenen aus einem Objekt lesen von dem ich weiß, dass es ein mehrdimensionaler Array ist? Allgemeine Java-Themen 3
H Objekt speichern und laden Allgemeine Java-Themen 1
H Objekt speichern und laden Allgemeine Java-Themen 1
J Wie kann ich von Vornherrein einen Fokus auf ein Objekt entfernen? Allgemeine Java-Themen 3
J Information von getSource() Objekt auslesen Allgemeine Java-Themen 1
Drachenbauer Wie stelle ich fest, ob ein Objekt in meinem Array vorkommt? Allgemeine Java-Themen 5
S Variable als Objekt Name Allgemeine Java-Themen 3
D Input/Output Zwischen zwei ID-Räumen unterscheiden und Objekt löschen Allgemeine Java-Themen 16
L Objekt aus Objekt-array "löschen" Allgemeine Java-Themen 2
T Objekt mit String und Int aus TxT Datei erstellen Allgemeine Java-Themen 23
T Objekt in Array packen Allgemeine Java-Themen 6
K Methodenaufruf mit String / String zu Objekt konvertieren Allgemeine Java-Themen 8
S Neues Objekt darstellen Allgemeine Java-Themen 4
J Best Practice Objekt an alle Klassen verteilen ( Discord Bot ) Allgemeine Java-Themen 7
D Objekt-Suche mit mehreren optionalen Parametern Allgemeine Java-Themen 6
M Klassen Objekt weiter geben Allgemeine Java-Themen 1
B Klassen Objekt erzeugen und Konstruktor aufrufen - Welche Lösung ist besser? Allgemeine Java-Themen 2
L Variablen Eigenes Objekt wie z.B. einen Integer zuweisen Allgemeine Java-Themen 3
D Konstruktor - jedes Objekt einzeln erzeugen - alternative? Allgemeine Java-Themen 8
S Applet Überprüfen ob ein Objekt angeklickt wurde Allgemeine Java-Themen 2
RalleYTN 3D Objekt Translation basierend auf Rotation (Probleme mit Z Rotation) Allgemeine Java-Themen 0
B Von String zu <Objekt> ||Speichern/Laden Allgemeine Java-Themen 17
G Neues Objekt aus List<JsonObject> mit Stream Allgemeine Java-Themen 4
P Threads Objekt im Konstruktor anders wie im Run()-Block Allgemeine Java-Themen 10
R Objekt funktioniert nicht auf iOS Allgemeine Java-Themen 15
K Textdatei als Objekt Allgemeine Java-Themen 4
Viktim Classenname zu Objekt Allgemeine Java-Themen 4
P Entity Objekt Methoden vs Service methoden Allgemeine Java-Themen 2
D Datentypen Klassenattribut aus Objekt in generischer Liste Allgemeine Java-Themen 15
O Klassen Bruch im gleichen Objekt Speichern Allgemeine Java-Themen 1
P Liste zu Objekt umwandeln Allgemeine Java-Themen 4
C Liste checken auf MINDESTENS ein Objekt | Bukkit Allgemeine Java-Themen 3
K Best Practice JFrame Objekt allgemein zugänglich machen Allgemeine Java-Themen 8
B ArrayList in ein Objekt legen Allgemeine Java-Themen 1
D Objekt entlang eines Funktionsgraphens bewegen Allgemeine Java-Themen 6
M Objekt serialisieren/deserialisieren und in einer SQLite-Datenbank speichern Allgemeine Java-Themen 3
D Java Objekt als Service in Runtime registrieren Allgemeine Java-Themen 1
S Interaktion mit einer website (website als Objekt?) Allgemeine Java-Themen 3
J OOP Überwachen, ob ein Objekt erzeugt wird Allgemeine Java-Themen 9
S Byte Array welches in Laufzeit aufgelöst wird // Objekt Array Allgemeine Java-Themen 3
Thallius Hash über serialisiertes Objekt? Allgemeine Java-Themen 3
Developer_X Input/Output Serialisiertes Objekt speichern und laden Allgemeine Java-Themen 1
C Generics Objekt in ArrayList Allgemeine Java-Themen 2
L Klassen Konstruktor soll Objekt anderer Klasse erzeugen Allgemeine Java-Themen 2
F Neues Objekt aus .CSV definition Allgemeine Java-Themen 3
K Methoden Objekt wird nicht erkannt Allgemeine Java-Themen 11
P Objekt mit verschiedenen Datentypen Allgemeine Java-Themen 5
T Objekt kontaktiert seinen "erzeuger" Allgemeine Java-Themen 5
S Objekt orientierte Programmierung Allgemeine Java-Themen 7
C Objekt Datenverlust nach Methodenaufruf Allgemeine Java-Themen 9
H JavaFX Von einer Methode auf stage-Objekt zugreifen Allgemeine Java-Themen 3
T WeakReference/PhantomReference: Mitbekommen WELCHES Objekt nun GC'ed wird Allgemeine Java-Themen 2
T Class-Objekt mit URLClassloader Allgemeine Java-Themen 7
P Konsoleneingabe übernehmen und Objekt instanzieren. Allgemeine Java-Themen 5
E Auf Java-Objekt aus anderer Instanz zugreifen Allgemeine Java-Themen 26
L Klassen Polymorphie:2 Attribute gleichen Namens in einem Objekt Allgemeine Java-Themen 6
P Objekt Array in Datei Speichern Allgemeine Java-Themen 3
F Dynamisch ein Objekt einer bestimmten Subklasse erstellen Allgemeine Java-Themen 7
D Player Objekt - Frame über Server anzeigen lassen. Allgemeine Java-Themen 3
V Objekt löschen Allgemeine Java-Themen 7
A OOP Wie auf Objekt der Superklasse zugreifen? Allgemeine Java-Themen 6
S Datei in File-Objekt mit UTF-8 einlesen Allgemeine Java-Themen 2
M neues Objekt speichern, nicht Referenz Allgemeine Java-Themen 10
B synchronisierter zugriff auf Objekt Allgemeine Java-Themen 6
F Objekt einer Datei verschieben, aber Verzeichnispfad fehlt Allgemeine Java-Themen 6
C Objekt Typ herausfinden Allgemeine Java-Themen 5
E Objekt beim Erzeugen in ArrayList Allgemeine Java-Themen 9
M Objekt prüfen auf null ->Invocation Target Exception??? Allgemeine Java-Themen 2
M Objekt aus Liste in Liste suchen/löschen Allgemeine Java-Themen 6
D Eigenen Objekt Pool Allgemeine Java-Themen 15
C blueJ: Objekt wird nicht in Objektleiste angezeigt Allgemeine Java-Themen 8
T Objekt 2x deserialisieren, aber nur 1x im Heap haben? Allgemeine Java-Themen 4
sambalmueslie Benachrichtigung bei neuer Objekt-Instanz Allgemeine Java-Themen 5
U Konstante in Objekt definieren Allgemeine Java-Themen 6
D this mit Objekt überschreiben Allgemeine Java-Themen 17
R Synchronized - auf welchem Objekt Allgemeine Java-Themen 16
E Objekt erstellen Allgemeine Java-Themen 7
M Timer von nicht existiertem Objekt stopen Allgemeine Java-Themen 5
M Swing-Frontend abhängig von ausgewähltem Objekt Allgemeine Java-Themen 4
J Lebt das Objekt noch?? Allgemeine Java-Themen 12
K Objekt einer konkreten Implementierung eines Interfaces durch übergebenen String Allgemeine Java-Themen 2
K Objekt-Austausch zwischen zwei Programmen über System-Clipboard Allgemeine Java-Themen 5
S Performance Frage: Objekt oder static? Allgemeine Java-Themen 33
B Speicherverbrauch Objekt-Referenz Allgemeine Java-Themen 11
D Browser-Objekt erzeugen Allgemeine Java-Themen 8
B FileWriter / FileReader testen / Mock-Objekt für Unit Tests? Allgemeine Java-Themen 6
A Iterationen einer XML-Datei in einem Objekt sichern Allgemeine Java-Themen 5
R Objekt zur Laufzeit zerstören? Allgemeine Java-Themen 12
hdi Frage zur Objekt Initialisierung Allgemeine Java-Themen 4
X Prozess-Objekt nach Ausführung der destroy-Methode null oder nicht null ? Allgemeine Java-Themen 10
T Serialisiertes Objekt über Socket nachladen Allgemeine Java-Themen 8
G Entity Objekt Allgemeine Java-Themen 2

Ähnliche Java Themen

Neue Themen


Oben