Cryptage/décryptage fichier [Résolu]

aurelbobol6 36 Messages postés jeudi 29 mars 2007Date d'inscription 4 février 2009 Dernière intervention - 16 janv. 2008 à 12:27 - Dernière réponse : Twinuts 5261 Messages postés dimanche 4 mai 2003Date d'inscription 20 avril 2018 Dernière intervention
- 17 janv. 2008 à 18:24
Bonjour, voila j'ai fais un petit programme pour copier deux fichiers. J'ai un fichier "original.exe" et je le crypte en "originalCrypte.exe", jusque la tout vas bien, la copie s'est bien déroulée.. mais lorsque je souhaite décrypter mon fichier  "originalCrypte.exe" pour le copier à "originalNouveau.exe", j'ai un BadPaddingException qui se passe et je ne sais aps trop quoi faire.
J'ai fais quelques recherche a ce sujet et j'ai vu qu'il fallait utiliser il me semble cipher.getBlockSize() et cipher.getOutputSize(arg0) mais je n'ai pas tout compris.
Autre petit détail, mon fichier original fait 5,02Mo, le originalCrypte fait 5,06Mo et le fichier originalNouveau 5,10Mo.
Je vous ai laissé mon code, si quelqu'un peut m'aider, ce serait vraiment sympa et super arrangeant. Merci d'avance

import ....

public class TestClass {
   private static Cipher cipherCrypt = null;
   private static Cipher cipherDecrypt = null;
   private static SecretKey key = null;
 
   public static void main(String[] args) {
    try {
     byte[] cle = (new String("password")).getBytes(); // 24 caractères
     key = new SecretKeySpec(cle, "Blowfish");
     cipherCrypt = Cipher.getInstance("Blowfish");
     cipherDecrypt = Cipher.getInstance("Blowfish");
     cipherCrypt.init(Cipher.ENCRYPT_MODE, key);
     cipherDecrypt.init(Cipher.DECRYPT_MODE, key);
     
     start("c:/temp/original.exe", "c:/temp/originalCrypte.exe", cipherCrypt);
     start("c:/temp/originalCrypte.exe", "c:/temp/originalNouveau.exe", cipherDecrypt);
    }catch(Exception e) {
     e.printStackTrace();
    }
   }
 
   private static void start(String entree, String sortie, Cipher cipher) throws IOException, IllegalBlockSizeException, BadPaddingException
       {
       byte[] input ;
       FileInputStream fIn = new FileInputStream(entree);
       FileOutputStream fOut = new FileOutputStream(sortie);
       FileChannel canalIn = fIn.getChannel();
       FileChannel canalOut = fOut.getChannel();
       ByteBuffer buffer = ByteBuffer.allocate(1024);
       int nombreLu = 0;
       while (nombreLu != -1) {
           buffer.clear();
           nombreLu = canalIn.read(buffer);
           if (nombreLu !=-1) {
                   buffer.flip();
                input = cipherCrypt.doFinal(buffer.array());
                canalOut.write(ByteBuffer.wrap(input));
                   }
            }
       canalIn.close();
       canalOut.close();
       fIn.close();
       fOut.close();
    }
  }
Afficher la suite 

10 réponses

Répondre au sujet
Twinuts 5261 Messages postés dimanche 4 mai 2003Date d'inscription 20 avril 2018 Dernière intervention - 17 janv. 2008 à 16:05
+3
Utile
Salut,

je ne peux pas te donner le code, mais voici un lien qui devrait régler le problème : ICI
Note : Il est préférable que tu utilises un algo plus évolué et surtout plus sécurisé que le DES qui est trop facilement decryptable ^^

------------------------------------
"On n'est pas au resto : ici on ne fait pas dans les plats tout cuits ..."

OoWORAoO
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de Twinuts
Twinuts 5261 Messages postés dimanche 4 mai 2003Date d'inscription 20 avril 2018 Dernière intervention - 17 janv. 2008 à 18:24
+3
Utile
Salut,

oui si ça résoud ton problème ^^

------------------------------------
"On n'est pas au resto : ici on ne fait pas dans les plats tout cuits ..."

OoWORAoO
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de Twinuts
aurelbobol6 36 Messages postés jeudi 29 mars 2007Date d'inscription 4 février 2009 Dernière intervention - 16 janv. 2008 à 13:29
0
Utile
j'ai oublié une erreur de modification dans la méthode start:

lihne 51: input = cipherCrypt.doFinal(buffer.array());
est remplacé par
input = cipher.doFinal(buffer.array());

et donc voici mon erreur

javax.crypto.BadPaddingException: Given final block not properly padded
    at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
    at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
    at com.sun.crypto.provider.BlowfishCipher.engineDoFinal(DashoA13*..)
    at javax.crypto.Cipher.doFinal(DashoA13*..)
    at TestClass.start(TestClass.java:51)
    at TestClass.main(TestClass.java:31)

pouvez vous m'aider svp..
Commenter la réponse de aurelbobol6
Twinuts 5261 Messages postés dimanche 4 mai 2003Date d'inscription 20 avril 2018 Dernière intervention - 16 janv. 2008 à 15:13
0
Utile
Salut,

j'ai eu exactement le même problème que toi... la solution que j'ai trouvé consiste à mettre le même IV entre l'application qui code et celle qui décode le message...

exemple pour du DES :

import java.security.Security;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

public class Des {
    private static final String DEFAULT_ENCODING= "UTF-8";
    private BASE64Decoder decoder64 = null;
    private BASE64Encoder encoder64 = null;
    private SecretKey secretKey    = null;
    private Cipher cipher = null;
    private IvParameterSpec ips = null;

    public Des(final String secretKey) throws Exception {
        decoder64 = new BASE64Decoder();
        encoder64 = new BASE64Encoder();
        Security.addProvider(new com.sun.crypto.provider.SunJCE());
        final DESKeySpec keySpec = new DESKeySpec(secretKey.getBytes(DEFAULT_ENCODING));
        final SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
        this.secretKey = keyFactory.generateSecret(keySpec);
        synchronized (Cipher.class) {
            cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
        }
        ips = new IvParameterSpec("azerty".getBytes());// préparation de l'IV
    }

    public String encode(final String plainText) throws Exception {
        final byte[] utf8 = plainText.getBytes(DEFAULT_ENCODING);
        byte b[] = null;
        synchronized (cipher) {
            cipher.init(Cipher.ENCRYPT_MODE, secretKey, ips );
            b = cipher.doFinal(utf8);
        }
        return encoder64.encode(b);
    }

    public String decode(final String cipherText) throws Exception {
        final byte b[] = decoder64.decodeBuffer(cipherText);
        byte[] utf8 = null;
        synchronized (cipher) {
            cipher.init(Cipher.DECRYPT_MODE, secretKey, ips );
            utf8 = cipher.doFinal(b);
        }
        return new String(utf8, DEFAULT_ENCODING);
    }
}

au passage il est préférable de passer par du base64, afin d'éviter les problèmes d'encodage... surtout lorsque le message passe d'un PC ayant un encodage de caractères UTF-8 vers un PC ayant un encodage de caractères en ISO.

------------------------------------
"On n'est pas au resto : ici on ne fait pas dans les plats tout cuits ..."

OoWORAoO
Commenter la réponse de Twinuts
aurelbobol6 36 Messages postés jeudi 29 mars 2007Date d'inscription 4 février 2009 Dernière intervention - 16 janv. 2008 à 15:35
0
Utile
j'ai fait excatement comme toi (sauf base64) ... mais ca ne marche toujours pas! merci quand mm. J'ai même essayé avec ton code à toi (donc même constructeur, même méthode... et base 64).J'ai toujours le même problème avec ce code la:

public class TestClass {
   private static Cipher cipherCrypt = null;
   private static Cipher cipherDecrypt = null;
   private static IvParameterSpec ips = null;
   private static final String DEFAULT_ENCODING= "UTF-8";
   private static SecretKey secretKey    = null;
 
   public static void main(String[] args) {
    try {
    Security.addProvider(new com.sun.crypto.provider.SunJCE());
    final DESKeySpec keySpec = new DESKeySpec("secretKey".getBytes(DEFAULT_ENCODING));
    final SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
    secretKey = keyFactory.generateSecret(keySpec);
    synchronized (Cipher.class) {
        cipherCrypt = Cipher.getInstance("DES/CBC/PKCS5Padding");
        cipherDecrypt = Cipher.getInstance("DES/CBC/PKCS5Padding");
    }
    ips = new IvParameterSpec("azertyaz".getBytes());// préparation de l'IV
    cipherCrypt.init(Cipher.ENCRYPT_MODE, secretKey, ips);
    cipherDecrypt.init(Cipher.DECRYPT_MODE, secretKey, ips);
   
    
    start("c:/temp/original.exe", "c:/temp/originalCrypte.exe", cipherCrypt);
    start("c:/temp/originalCrypte.exe", "c:/temp/originalNouveau.exe", cipherDecrypt);
    }catch(Exception e) {
     e.printStackTrace();
    }
   }
 
   private static void start(String entree, String sortie, Cipher cipher) throws IOException, IllegalBlockSizeException, BadPaddingException
       {
       byte[] input ;
       FileInputStream fIn = new FileInputStream(entree);
       FileOutputStream fOut = new FileOutputStream(sortie);
       FileChannel canalIn = fIn.getChannel();
       FileChannel canalOut = fOut.getChannel();
       ByteBuffer buffer = ByteBuffer.allocate(1024);
       int nombreLu = 0;
       while (nombreLu != -1) {
           buffer.clear();
           nombreLu = canalIn.read(buffer);
           if (nombreLu !=-1) {
                   buffer.flip();
                input = cipher.doFinal(buffer.array());
                canalOut.write(ByteBuffer.wrap(input));
                   }
            }
       canalIn.close();
       canalOut.close();
       fIn.close();
       fOut.close();
    }
}

as-tu une autre idée ou vois-tu une ereur dans mon code? stp . merci en tout cas de ta réponse
Commenter la réponse de aurelbobol6
Twinuts 5261 Messages postés dimanche 4 mai 2003Date d'inscription 20 avril 2018 Dernière intervention - 16 janv. 2008 à 16:36
0
Utile
Salut,

bah pour commencer je me suis planté dans le choix de l'IV vu qu'il faut une taille de 8 bytes....
bref tu prends le code ci-dessus et tu change l'IV pour avoir 8 bytes
exemple :
ips = new IvParameterSpec("azertyui".getBytes());// préparation de l'IV

ensuite voici un ptit code d'exemple (qui fonctionne chez moi) pour utiliser la classe Des ci-dessus :
public class TestDes {

    public static void main(String[] args) {
        try {
            Des des = new Des("ma secret key");
            String source = "hello de javafr";
            System.out.println(source);
            String encoded = des.encode(source);
            System.out.println(encoded);
            String decoded = des.decode(encoded);
            System.out.println(decoded);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

------------------------------------
"On n'est pas au resto : ici on ne fait pas dans les plats tout cuits ..."

OoWORAoO
Commenter la réponse de Twinuts
aurelbobol6 36 Messages postés jeudi 29 mars 2007Date d'inscription 4 février 2009 Dernière intervention - 17 janv. 2008 à 13:22
0
Utile
ca ne marche toujours pas.. pourtant j'ai pris ton code tel quel sauf que j'ai voulu faire ca avec un fichier.. personne n'a une autre idée? svp
Commenter la réponse de aurelbobol6
Twinuts 5261 Messages postés dimanche 4 mai 2003Date d'inscription 20 avril 2018 Dernière intervention - 17 janv. 2008 à 13:40
0
Utile
Salut,

........ j'ai meme refait une code avec un fichier et ça fonctionne impec.... sauf que je n'utilise absolument pas ta technique pour lire et ecrire dans le fichier....

------------------------------------
"On n'est pas au resto : ici on ne fait pas dans les plats tout cuits ..."

OoWORAoO
Commenter la réponse de Twinuts
aurelbobol6 36 Messages postés jeudi 29 mars 2007Date d'inscription 4 février 2009 Dernière intervention - 17 janv. 2008 à 13:42
0
Utile
tu utilise quelle technique? pck moi j'utilise celle ci car après je vais la mettre dans un socketchannel ... et mes fichiers sont de taille de 100Mo environ pour mon projet. merci en tout cas pour tes rép
Commenter la réponse de aurelbobol6
aurelbobol6 36 Messages postés jeudi 29 mars 2007Date d'inscription 4 février 2009 Dernière intervention - 17 janv. 2008 à 17:51
0
Utile
Merci, merci, merci mille fois, tu m'arranges de bien des soucis... encore merci
P.S : il faut que je clique sur réponse acceptée?
Commenter la réponse de aurelbobol6

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.