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



## Jackcarver12 (1. Apr 2020)

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.

```
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:


```
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


----------



## Xyz1 (1. Apr 2020)

Vielleicht hilft diese Antwort hier https://www.java-forum.org/thema/objekt-in-bytestream-umwandeln.187784/#post-1215774 , ich habe dieses Thema zu spät bemerkt...
lg


----------



## Xyz1 (2. Apr 2020)

Jackcarver12 hat gesagt.:


> 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 (2. Apr 2020)

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

ok hier ein Update meines Codes:

```
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


----------



## mihe7 (4. Apr 2020)

Jackcarver12 hat gesagt.:


> 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?


Das hört sich ganz danach an, aber warum probierst Du es nicht einfach aus?!?


----------

