Objekt mit RSA und AES verschlüsseln und entschlüsseln HILFE

Jackcarver12

Mitglied
Hallo Leute,
folgendes Problem:

Ich möchte ein mir übergebenes Objekt(selbsterstellte Klasse "Nachricht") namens "msg" verschlüsseln.
Die Klasse "Nachricht" kann aus Text,Bildern etc bestehen, was zuallererst nach meinen Erkenntnissen keine Rolle spielt, weil wir dann ja eh einen Stream haben bzw ein byte[].
Nach meinen Recherchen, gibt es jetzt zwei Wege:
1) Ich erstelle einen ObjectOutputStream und schreibe da mein "msg"-Objekt rein
2) Diesen oos (ObjectOutputStream) wandle ich dann in einen CipherOutputStream um.
3)In diesem Stream ist mein Objekt meiner Erkenntnis nach verschlüsselt.
Java:
public EncryptedMessage encrypt(PublicKey pubkey, Nachricht msg) {
        try {
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, pubkey);

            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            CipherOutputStream cos = new CipherOutputStream(bos, cipher); //verschlüsselt mit dem RSA Verfahren? bereits hier?
            ObjectOutputStream oos = new ObjectOutputStream(cos);
            oos.writeObject(msg);

            byte[] encryptedBytes = bos.toByteArray();
            
            oos.flush(); //warum flusht er hier?

            //return new EncryptedMessage(encryptedBytes);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

An dieser Stelle könnte ich nun nach meinem Verständnis auch das verschlüsselte byte[] encryptedBytes returnen? Korrekt?

Oder Alternative 2:
Mein Objekt serialisieren und zu der Datei einen Stream erstellen.
Dann hätte ich einen Input bzw OutputStream den ich wieder verschlüsseln könnte weil ich ihn in ein byte[] umwandeln könnte.


Schließlich soll auf der EmpfängerSeite wieder entschlüsselt werden:

Java:
public Nachricht decrypt(PrivateKey privkey, EncryptedMessage m) {
        if (m.getContent() != null && m.getContent().length > 0) {
            try {
                Cipher cipher = Cipher.getInstance("RSA");
                cipher.init(Cipher.DECRYPT_MODE, privkey);

                ByteArrayInputStream bin = new ByteArrayInputStream(
                        m.getContent());
                CipherInputStream cin = new CipherInputStream(bin, cipher);
                ObjectInputStream in = new ObjectInputStream(cin);

                return (Nachricht) in.readObject();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        return null;
        
    }

somit müsste er mir aus dem inputStream mein Objekt auslesen und returnen.
Ist das korrekt?

Ich hoffe auf viele Anmerkungen Antworten und Korrekturen.
Vielen Dank
LG
 
X

Xyz1

Gast
oos.flush(); //warum flusht er hier?
Eh Du musst den ObjectOutputStream flushen, damit der Schreibvorgang beendet wird. Ansonsten hätte der ByteArrayOutputStream beim Aufruf von toByteArray(); nicht alle Bytes, wäre also unvollständig. Wenn Du "try with resources" verwendest, dann wird automatisch geflusht nach allen Schreibvorgängen... Der ObjectOutputStream verwendet einen internen Zwischenspeicher und muss es bei einem write... nicht sofort schreiben. Deswegen kann es passieren, dass ein unvollständiges Objekt ver- oder entschlüsselt wird, was dann natürlich zu einer Exception führt.

Also, wo möglich, da ein "try with resources" (Java >= 7) verwenden, das hat auch den Vorteil, dass man das schließen der Streams nicht vergisst. (und weniger "boilerplate code"...)
 

Jackcarver12

Mitglied
Hey vielen Dank für deine Hilfe, bin froh dass du auch hier am Start bist ;)

ok hier ein Update meines Codes:
Code:
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;

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


public class Crypter
{

    
    private static final String text="Hallo";
    

    public static byte[] encryptObject(Nachricht msg,PublicKey pubkey) //verschlüsselt das Objekt im CipherStream
    {
        Cipher cipher;
        try
        {
            cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, pubkey);

            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            CipherOutputStream cos = new CipherOutputStream(bos, cipher);
            ObjectOutputStream oos = new ObjectOutputStream(cos);
            oos.writeObject(msg);
            
            byte[] encryptedBytes = bos.toByteArray(); 
            return encryptedBytes;
            
            //weiss nicht was ich zurückgeben soll
            //den ObjectOutputStream
            //oder die verschlüsselten Bytes
            
            
            //byte[] encryptedBytes = bos.toByteArray(); 

        } catch (NoSuchAlgorithmException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchPaddingException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvalidKeyException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
                
        return null;
        
    }

    public static Nachricht decryptObject(PrivateKey privKey,byte[] encryptedBytes) //entschlüsselt das Object
    {
        Nachricht  msg=null;
        try
        {
            Cipher cipher = Cipher.getInstance("RSA");

            cipher.init(Cipher.DECRYPT_MODE, privKey);
            ByteArrayInputStream bin = new ByteArrayInputStream(encryptedBytes);
            CipherInputStream cin = new CipherInputStream(bin, cipher);
            ObjectInputStream in = new ObjectInputStream(cin);
            return (Nachricht) in.readObject();

            
        } catch (InvalidKeyException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchPaddingException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ClassNotFoundException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        

        return null;
    }
    

    
    
    //verschlüsselt Text
    public static byte[] encryptBytes(PublicKey key, byte[] plain)
    {
        byte[] chiffre=null;
        
        try
        {
            Cipher cipher=Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, key);
            
            chiffre= cipher.doFinal(plain);
            
            return chiffre; //verschlüsseltes byte[]
            
        } catch (NoSuchAlgorithmException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchPaddingException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvalidKeyException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalBlockSizeException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (BadPaddingException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        return null;
        
    }
    //entschlüsselt Text
    public static byte[] decryptBytes(PrivateKey key, byte[] chiffre)
    {

        try
        {
            Cipher cipher=Cipher.getInstance("RSA");
            cipher.init(cipher.DECRYPT_MODE,key);
            
            byte[] btext= cipher.doFinal(chiffre);
            return btext;
            
            
        } catch (NoSuchAlgorithmException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchPaddingException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvalidKeyException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalBlockSizeException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (BadPaddingException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        return null;
    }
    
    
    
    public static void main(String [] args)
    {
        
        
        try
        {

            
            //KeyPair und Keys managen
            KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
            keyPairGen.initialize(1024);
            KeyPair keypair=keyPairGen.generateKeyPair();
            PrivateKey privKey=keypair.getPrivate();
            PublicKey pubKey=keypair.getPublic();
            
            //Text->Byte
            //Byte->Text
            System.out.println("\n\nTest");
            String testtext= "h";
            byte[] testbyte=testtext.getBytes();
            System.out.println(testbyte);
            testtext=new String(testbyte);
            System.out.println(testtext);
            System.out.println("\n\n");
            
            //Text->Byte[] text
            //byte[] text->encrypt
            //byte[]encrypt-> decrypt
            //byte[] decrypt->String
            System.out.println("Ausgangstext:");
            System.out.println(text);
            System.out.println("1)Text als byte[] unverschlüsselt");
            byte[] bytetext=text.getBytes(); //in byte[] umgewandelt
            System.out.println( bytetext); //bytetext anzeigen lassen
            System.out.println("2) byte[] verschlüsselt");
            byte[] encrypt=encryptBytes(pubKey,bytetext); //verschlüsseln des byte[]
            System.out.println( encrypt); //ausgeben lassen
            System.out.println("3) byte[] entschlüsselt");
            byte[]decrypt=decryptBytes(privKey,encrypt); //entschlüsseln lassen
            String text=new String(decrypt);
            System.out.println(text);
            //String s = new String(bytes);
            
            //Object->byte[]
            //byte[] object-> byte[] encrypt
            //byte[] encrypt -> byte[]decrypt
            //byte[] decrypt -> object
            System.out.println("Ausgangsobjekt:");
            Nachricht  msg=new Nachricht();
            msg.setNachricht("Hallo");
            //verschlüsseln des Objekts
            byte[] vObject=encryptObject(msg,pubKey);
            System.out.println("Test ");
            Nachricht neuemsg=decryptObject(privKey,vObject);
            System.out.println("Test2");
            String nachricht=neuemsg.getNachricht();
            System.out.println(nachricht);
            
            
            

            
            
            
            
            
            
        } catch (NoSuchAlgorithmException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    
        
        
        
        
        
    }

}

ich erhalte eine BadPaddingException.
Die JavaDoku ist was das angeht leider nicht gerade aussagekräftig.
Woran könnte es denn liegen?
Er gibt mir beide TestStrings aus. Also er erreicht die Stellen im Code.
Liegt es hier vielleicht auch am flushen?
oder fehlt ein close()?
LG
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
OnDemand Json Objekt leeres Array beim lesen Netzwerkprogrammierung 9
I Socket ObjectOutputStream-Socket: Objekt wird falsch übertragen Netzwerkprogrammierung 2
L Java RMI Objekt konsistenz Netzwerkprogrammierung 1
P RMI - Neue eigene Instanz für jeden Aufruf auf nicht serialisierbares Objekt - wie? Netzwerkprogrammierung 0
R RMI und Entferntes Objekt (EO) Netzwerkprogrammierung 0
A Server Antwort enthält JSON Objekt/Array Netzwerkprogrammierung 8
N Selbes URL Objekt für alle Requests nutzen Netzwerkprogrammierung 7
B udp erkennen um welches objekt es sich handelt / max size Netzwerkprogrammierung 5
S Socket Client liest leeres Objekt Netzwerkprogrammierung 10
D Remote-Objekt-Server : Alternative Methodenaufruflogik zu Reflection und hart codiert Netzwerkprogrammierung 5
K RMI Angemeldetes Objekt nicht aktuell? Netzwerkprogrammierung 9
D [CORBA] Eigenes Objekt in idl? undefined type Netzwerkprogrammierung 5
M Objekt über Object-Stream, empfange "alte" Daten Netzwerkprogrammierung 2
M Objekt über socket senden/empfangen Netzwerkprogrammierung 3
H Objekt von JSP an Servlet übergeben Netzwerkprogrammierung 4
T Wieso ist mein Objekt leer? Netzwerkprogrammierung 6
L RMI-Objekt zwischen zwei RMI-Servern kopieren Netzwerkprogrammierung 2
S Objekt Felder versenden Netzwerkprogrammierung 5
W Objekt über Socket übertragen Netzwerkprogrammierung 14
G Problem bei Objekt senden von server zu client Netzwerkprogrammierung 6
P RMI - Objekt als Rückgabeparameter Netzwerkprogrammierung 3
M RMI - Ein Objekt für Alle? Netzwerkprogrammierung 5
H Versenden von Objekt Netzwerkprogrammierung 2
J Prblem, wenn im verschickten Objekt ein Array ist Netzwerkprogrammierung 4
brainless Client Server Kommunikation verschlüsseln Netzwerkprogrammierung 13
L End zu End verschlüsseln? Netzwerkprogrammierung 6
S oAuth Key's verstecken/verschlüsseln/speichern Netzwerkprogrammierung 6
G RMI SSL verschlüsseln Netzwerkprogrammierung 2
M DatenStrom (text) entschlüsseln. Netzwerkprogrammierung 3

Ähnliche Java Themen


Oben