I have just discovered the PBE method to generate a "salty" key in order to encrypt an object (here, a string).
I do not know much how all this works, but the lessons I had made me want to go a little further and therefore to create my own salege and everything that follows without leaving java "everything to do".
So I developed methods that are used to encrypt and decrypt a message, and everything seems to work very well ... But in fact, it works weirdly, because the message I find at the end is present, but present with extra characters!
I find it hard to understand how this is done.
Could you enlighten me on this question?
The code of my class below:
package fr.doranco.cryptage.pbe;
import fr.doranco.utils.Utils;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import java.util.Random;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
/**
 *
 * @author Boule
 */
public abstract class CryptagePBE {
    private static final int KEY_SIZE = 128;
    private static final String KEY_ALGO = "AES";
    private static final String ALGOTRANSFORM = "AES/CBC/PKCS5Padding";
    private static final String KDF = "PBKDF2WithHmacSHA1";
    private static final int ITERATION = 1000;
    private static final Random RANDOM = new SecureRandom();
    private CryptagePBE() {
    }
    public static final byte[] encrypter(Object objetACrypter, SecretKey clePBE) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, UnsupportedEncodingException, IllegalBlockSizeException, BadPaddingException, IOException, InvalidAlgorithmParameterException {
        Cipher cipher = Cipher.getInstance(ALGOTRANSFORM);
        cipher.init(Cipher.ENCRYPT_MODE, clePBE,new IvParameterSpec(new byte[16]));
        byte[] objetBytes = Utils.convertToBytes(objetACrypter);
        byte[] cipherBytes = cipher.doFinal(objetBytes);
        return cipherBytes;
    }
    public static final byte[] decrypter(byte[] stringCrypte, SecretKey cle, String encodage) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException, InvalidAlgorithmParameterException {
        Cipher cipher = Cipher.getInstance(ALGOTRANSFORM);
        cipher.init(Cipher.DECRYPT_MODE, cle, new IvParameterSpec(new byte[16]));
        //Ne pas oublier de caster le retour afin de récupérer l'objet désiré !
        return cipher.doFinal(stringCrypte);
    }
    public static final SecretKey generatePBEKey(String password) throws NoSuchAlgorithmException, InvalidKeySpecException {
        SecretKey clePBE = null;
        char[] passwordTochar = password.toCharArray();
        PBEKeySpec pbeKeySpec = new PBEKeySpec(passwordTochar, CryptagePBE.getNextSalt(), ITERATION, KEY_SIZE);
        //On vide le tableau de charactère du mot de passe.
        password = "";
        for (int j = 0; j < passwordTochar.length; j++) {
            passwordTochar[j] = 0;
        }
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(KDF);
        SecretKey keyPBE = keyFactory.generateSecret(pbeKeySpec);
        clePBE = new SecretKeySpec(keyPBE.getEncoded(), KEY_ALGO);
        return clePBE;
    }
    public static byte[] getNextSalt() {
        byte[] salt = new byte[16];
        RANDOM.nextBytes(salt);
        return salt;
    }
    public static final byte[] convertKeyToBytes(SecretKey key) throws IOException {
        try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
                ObjectOutput out = new ObjectOutputStream(bos)) {
            out.writeObject(key);
            return bos.toByteArray();
        }
    }
    public static final SecretKey convertKeyFromBytes(byte[] keyData) throws IOException, ClassNotFoundException {
        try (ByteArrayInputStream bis = new ByteArrayInputStream(keyData);
                ObjectInput in = new ObjectInputStream(bis)) {
            return (SecretKey) in.readObject();
        }
    }
}
Here my main
public class Main {
    public static void main(String[] args) {
        try {
            SecretKey clePBE = CryptagePBE.generatePBEKey("coucou");
            String messageA = "Hi people";
            System.err.println("Original message : "+ messageA+" //Message in bytes array : "+Utils.convertToBytes(messageA));
            byte[] messageCrypte2 = CryptagePBE.encrypter(messageA, clePBE);
            System.err.println("Crypted message : "+messageCrypte2);
            byte[] messageDecrypte = CryptagePBE.decrypter(messageCrypte2, clePBE, "UTF8");
            System.err.println("Decrypted message : "+messageDecrypte);
        } catch (Exception ex) {
            System.err.println("Une erreur est survenue dans le main : " + ex);
        }
    }
    public Main() {
    }
}
And this is what I have in my output console :
Original message : Hi people //Message in bytes array : [B@704921a5
Crypted message : [B@31f924f5
Decrypted message : [B@5579bb86 //This will return "Hi people" but with a changed bytes array.
I wonder if it's a problem due to the encoding ?
Thank you !
Edit
Thx to @andreas who gave me the reason. The method to compare the both messages is to compare with Arrays.toString(myArray). With this method we can see the same array of bytes, not a different for both.
Here the full explaination of this : What's the simplest way to print a Java array?
