web-dev-qa-db-fra.com

Chiffrement et déchiffrement AES avec Java

Voici ce que je fais qui peut sembler un peu maladroit mais toute aide est appréciée concernant le problème. Je reçois un BadPaddingException. Lisez presque tous les sujets connexes mais n'avez pas trouvé la solution appropriée. Je suis nouveau dans la programmation de décryptage de cryptage et je dois l'implémenter dans l'une de mes applications Java.

Merci .. voici à quoi ressemble le code ....

public static void main(String[] args) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
    // TODO Auto-generated method stub
            String FileName="encryptedtext.txt";
            String FileName2="decryptedtext.txt";
            String pad="0"; 

            KeyGenerator KeyGen=KeyGenerator.getInstance("AES");
            KeyGen.init(128);

            SecretKey SecKey=KeyGen.generateKey();

            Cipher AesCipher=Cipher.getInstance("AES");
            AesCipher.init(Cipher.ENCRYPT_MODE,SecKey);

            byte[] byteText="My name is yogesh".getBytes();
            byte[] byteCipherText=AesCipher.doFinal(byteText);
            String cipherText = null;

            try {
                FileWriter fw=new FileWriter(FileName);
                BufferedWriter bw=new BufferedWriter(fw);
                bw.write(byteCipherText.toString());
                bw.close();
            }catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            try {
                FileReader fr=new FileReader(FileName);
                BufferedReader br=new BufferedReader(fr);
                cipherText=br.readLine();
                br.close();
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            AesCipher.init(Cipher.DECRYPT_MODE,SecKey);
            while(((cipherText.getBytes().length)%16)!=0)
            {
                cipherText=cipherText+pad;


            }

            byte[] bytePlainText=AesCipher.doFinal(cipherText.getBytes());
            FileWriter fw1;
            try {
                fw1 = new FileWriter(FileName2);
                BufferedWriter bw1=new BufferedWriter(fw1);
                bw1.write(bytePlainText.toString());
                bw1.close();

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






}
8
Yogesh D

Ici, ce que vous devez comprendre, c'est que le texte chiffré peut contenir des caractères non imprimables. Ainsi, lorsque vous utilisez readLine (), il ne vous donnera probablement pas tous les octets du fichier.

De plus, byteCipherText.toString() ne vous donne pas ce que vous pensiez obtenir. En Java, la méthode toString() ne donne pas la représentation sous forme de chaîne du contenu du tableau.

Il n'est pas nécessaire d'ajouter un remplissage au texte chiffré. Il est déjà rembourré.

import Java.nio.file.Files;
import Java.nio.file.Paths;
import javax.crypto.*;

public class Main {

    public static void main(String[] args) throws Exception {
        String fileName = "encryptedtext.txt";
        String fileName2 = "decryptedtext.txt";

        KeyGenerator keyGen = KeyGenerator.getInstance("AES");
        keyGen.init(128);

        SecretKey secKey = keyGen.generateKey();

        Cipher aesCipher = Cipher.getInstance("AES");


        byte[] byteText = "Your Plain Text Here".getBytes();

        aesCipher.init(Cipher.ENCRYPT_MODE, secKey);
        byte[] byteCipherText = aesCipher.doFinal(byteText);
        Files.write(Paths.get(fileName), byteCipherText);


        byte[] cipherText = Files.readAllBytes(Paths.get(fileName));

        aesCipher.init(Cipher.DECRYPT_MODE, secKey);
        byte[] bytePlainText = aesCipher.doFinal(cipherText);
        Files.write(Paths.get(fileName2), bytePlainText);
    }
}
15
bgamlath

Vous devez définir l'algorithme de remplissage que vous utilisez lorsque vous créez une instance de Cipher. Personnellement, j'utilise PKCS5 .

Vous devez donc changer:

Cipher AesCipher=Cipher.getInstance("AES");

à:

Cipher AesCipher=Cipher.getInstance("AES/CBC/PKCS5Padding");

CBC signifie Cipher-block chaining.

CBC nécessite IV pour être transmis. Vous voulez donc générer un IV aléatoire et le passer dans la méthode init:

byte[] iv = new byte[16];
SecureRandom random = new SecureRandom();
random.nextBytes(iv);
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
AesCipher.init(Cipher.ENCRYPT_MODE, SecKey, ivParameterSpec);

Remarque: il est recommandé d'éviter nombres/chaînes magiques dans votre code. Je suggère d'extraire les passes d'argument dans Cipher#getInstance à une constante.

9
Leri