IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2009
    Messages
    173
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2009
    Messages : 173
    Points : 187
    Points
    187
    Par défaut javax-crypto-Cipher: encryption avec entrée en 16 octets et sortie en 32 octets? (Taille fichiers doublée)
    Bonjour à tous,
    J'ai un problème avec la méthode doFinal(byte[] input) de Cipher. En entrée, je passe un tableau de 16 octets mais en sortie j'obtiens un tableau de 32 octets. Ceci fait que mes fichiers encryptés font le double de mes fichiers d'origine. Je souhaiterais réduire la taille de mes fichiers encyptés en obtenant, si possible, 16 octets en sortie de la fonction doFinal(byte[] input).

    Est-ce possible? Si non, y a t'il un moyen d'encrypter mes fichiers par un autre moyen (mais avec le même algorithme d'encryption derrière: AES avec clé en 16 bytes) tout en obtenant des fichiers qui soient moins lourds?

    Merci d'avance pour vos réponses.

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Février 2010
    Messages
    765
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 765
    Points : 1 037
    Points
    1 037
    Par défaut
    AES est un algorithme de chiffrement par bloc, classiquement : 16 ou 32 octets (128 ou 256 bits donc...)

    Tu as du confondre AES128 et AES256 pour obtenir des blocs de 256bits en sortie.

    C'est pas bien grave, tu as un bout de code où tu initialises ton Cipher ?

  3. #3
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2009
    Messages
    173
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2009
    Messages : 173
    Points : 187
    Points
    187
    Par défaut
    Merci pour ta réponse.

    Voici la partie du code correspondante (j'ai remplacé les valeurs de la clé^^):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    final SecretKeySpec keyspec = new SecretKeySpec(new byte[]{-106, -71, 95, -132, 10, -19, -77, 75, -90, 116, -99, -109, -117, -40, 56, 67 }, "AES");
    //...
    cipher = Cipher.getInstance("AES/ECB/PKCS5Padding", "SunJCE");
    //...
    cipher.init(Cipher.ENCRYPT_MODE, keyspec);
    La clé fait bien 16 bytes (ou octets) donc c'est bien de l'AES128 que j'utilises non? J'utilises plutot AES/ECB/PKCS5Padding pour être exact mais cela doit être du 128 bits selon la doc oracle:
    Every implementation of the Java platform is required to support the following standard Cipher transformations with the keysizes in parentheses:
    ...
    •AES/ECB/PKCS5Padding (128)

  4. #4
    Membre éprouvé
    Profil pro
    Inscrit en
    Février 2010
    Messages
    765
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 765
    Points : 1 037
    Points
    1 037
    Par défaut
    Pour l'instant je ne vois rien de spéciale, il y a peut-être un soucis après, tu peux mettre les méthodes de chiffrement et déchiffrement ?

    Autre remarque : utiliser le mode ECB avec une algorithme symétrique par bloc, c'est une mauvaise idée.
    Si ton message contient une longue suite identique, ton message chiffré ne le masquera pas.
    De plus des messages identiques seront chiffrés de manière identique. C'est très mauvais en sécurité.

    Pour bien faire il te faut obligatoirement un autre mode comme le CBC et un vecteur d'initialisation différent à chaque fois.

  5. #5
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2009
    Messages
    173
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2009
    Messages : 173
    Points : 187
    Points
    187
    Par défaut
    Merci pour ta réponse.

    Pour le choix du "AES/ECB/PKCS5Padding" c'est un choix du client mais découvrant le cryptage ta réponse est très instructive su ce point .

    En fait, j'ai compris pourquoi la taille des fichiers est doublée. Le code existant n'est pas le bon. En effet, on boucle en récupérant 16 octets et on applique doFinal() dessus qui lui en retourne 32 puis on écrit ces 32 alors qu'il faut boucler avec update() et faire un doFinal() à la fin comme ceci (je me suis fait ce petit code de test à partir d'un exemple trouvé sur ce forum):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
     
           final Cipher cipher =
            Cipher.getInstance("AES/ECB/PKCS5Padding", "SunJCE");
          // Encryptage
          cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(KEY_BYTES, "AES"));
          final InputStream in = new FileInputStream(inputFile);
          final OutputStream out = new FileOutputStream(outputFile);
          final int blockSize = cipher.getBlockSize();
          final int outputSize = cipher.getOutputSize(blockSize);
          final byte[] inBytes = new byte[blockSize];
          byte[] outBytes = new byte[outputSize];
     
          int inLength = 0;
          boolean done = false;
          while (!done) {
            inLength = in.read(inBytes);
            if (inLength == blockSize) {
              try {
                final int outLength =
                  cipher.update(inBytes, 0, blockSize, outBytes);
                System.out.println("entree : " + inLength);
                System.out.println("sortie : " + outBytes.length + " " + outLength);
                out.write(outBytes, 0, outLength);
              } catch (final ShortBufferException e) {
                e.printStackTrace();
              }
            } else
              done = true;
          }
     
          try {
            if (inLength > 0)
              outBytes = cipher.doFinal(inBytes, 0, inLength);
            else
              outBytes = cipher.doFinal();
            out.write(outBytes);
          } catch (final IllegalBlockSizeException e) {
            e.printStackTrace();
          } catch (final BadPaddingException e) {
            e.printStackTrace();
          }
    Avec cette manière, on obtient bien des fichiers qui font à peu près la même taille (la taille n'est plus doublée).

    Cependant, des fichiers ayant été encryptés avec l'ancienne manière, mettre en place cette nouvelle manière ne serait pas rétrocompatible pour le décryptage des anciens fichiers encodés. En effet, le décryptage marche sur les fichiers encryptés avec la nouvelle manière mais pas avec l'ancienne manière (du fait que ce sont des blocs de 32). Y a t-il un moyen de le détecter pour appliquer l'une ou l'autre des manières?

  6. #6
    Membre éprouvé
    Profil pro
    Inscrit en
    Février 2010
    Messages
    765
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 765
    Points : 1 037
    Points
    1 037
    Par défaut
    Non il faut tester les deux manière et voir si le résultat obtenu est logique.

    Sinon je signale juste que AES en mode ECB c'est extrêmement faible comme sécurité ... à toi de voir ...

Discussions similaires

  1. Déchiffrement image avec Crypto Cipher
    Par skullone dans le forum Général Python
    Réponses: 3
    Dernier message: 26/10/2011, 10h04
  2. Utilisation de la classe javax.crypto.Cipher
    Par Le Marlou dans le forum Sécurité
    Réponses: 7
    Dernier message: 24/02/2010, 14h04
  3. Tabulation dans une form avec entrée
    Par Cl@rk dans le forum Windows Forms
    Réponses: 4
    Dernier message: 23/05/2008, 12h09
  4. [SQL] Problème avec Entre [] et []
    Par samlepiratepaddy dans le forum Access
    Réponses: 8
    Dernier message: 11/11/2005, 11h33
  5. Crash de mon dvd encrypté avec xine
    Par Slein dans le forum Applications et environnements graphiques
    Réponses: 3
    Dernier message: 06/06/2004, 16h45

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo