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

Java Discussion :

[Cipher] Décryptage depuis un jar


Sujet :

Java

  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 [Cipher] Décryptage depuis un jar
    Salut à tous,
    J'ai un poblème lorsque je veux décrypter mes fichiers encryptés puis mis dans un jar.

    Je m'explique:
    Avant de faire mon traitement avec cipher pour décrypter, je fais ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    final ZipEntry ze =
            aJarFile.getEntry("toto.enc");
          final InputStream zin = aJarFile.getInputStream(ze);
    Or, j'ai l'impression que je n'obtiens pas le même InputStream que lorsque mon fichier est dézippé puis que je le récupère directement sous forme d'InputStream à partir du File.
    En effet, lorsque je dézippe le fichier de mon jar puis que je décypte, aucun problème. Par contre, si j'utilise le code donné plus haut pour obtenir mon InPutStream, alors le décyptage plante sur le doFinal() avec une IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher.
    Cela me laisse penser que les blocs obtenus à partir de l'InputStream du code du dessus, ne correspondent pas à ceux quand le fichier est dézippé.

    Pour résumer:
    - En utilisant le code au dessus pour obtenir l'InputStream à partir de mon jar et sur lequel je fais le décryptage = IllegalBlockSizeException
    - En dézippant manuellement mon jar, puis en créant un File à partir duquel je récupère mon InputStream sur lequel je fais le décryptage = pas de problème.

    C'est vraiment bizarre.

    Savez-vous comment obtenir un InputStream correct à partir du jar pour que cela fasse comme lorsque je dézippe svp?

    Je vous remercie d'avance.
    Diplomes: DUT informatique et Master 2 MIAGE.
    Développeur Java/J2EE (principalement), .NET (niveau scolaire mais je compte m'améliorer ) et Web (HTML, PHP...).

  2. #2
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Non, il n'y a pas de raison que ce soit différent. Si zipentry "modifait" les flux, on aurait de sacrés soucis à ce faire, plus aucune classe ne se chargerait.

  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
    Et pourtant l'InputStream n'est pas le même au niveau du contenu... D'ailleurs le code cité retourne... un java.util.zip.ZipFile$1 pour zin (je ne connais même pas, ne sais pas à quoi cela correspond et m'attendais plutôt à un descendant de InputStream comme FileInputStream ou ZipFileInputStream ou ZipInputStream). Le contenu des 2 InputStream n'est pas le même lorsque cela passe au décryptage au niveau des blocs. J'ai peut être mal fait quelque chose mais je ne pense pas... Cela marche si je décompresse avec 7zip puis que je décrypte le fichier dézippé mais pas lorsque c'est décrypté directement à partir du jar avec le code cité.

    Lorsque j'ouvre le jar avec un outil comme 7zip, je vois qu'il y a 2 tailles indiquées dont une compressée, ne serait-ce pas la source du problème? Je me dis que si la données est compressée, cela a forcément un impact sur l'InputStream et les blocs d'octets non?

    Je souhaiterais juste que le décryptage fonctionne lorsque le fichier encrypté est dans un jar.
    Diplomes: DUT informatique et Master 2 MIAGE.
    Développeur Java/J2EE (principalement), .NET (niveau scolaire mais je compte m'améliorer ) et Web (HTML, PHP...).

  4. #4
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 554
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 554
    Points : 21 615
    Points
    21 615
    Par défaut
    Citation Envoyé par philou44300 Voir le message
    Et pourtant l'InputStream n'est pas le même au niveau du contenu...
    Peut-être que ce n'est que ce que tu crois. Je dis pas que c'est totalement impossible, je dis que tu ne doutes pas assez de toi et que tu doutes trop vite d'une bibliothèque que tout le monde utilise toutes les minutes et sans soucis.

    Citation Envoyé par philou44300 Voir le message
    J'ai peut être mal fait quelque chose mais je ne pense pas...
    Ça pourrait être une bonne idée de nous laisser vérifier.

    Citation Envoyé par philou44300 Voir le message
    D'ailleurs le code cité retourne... un java.util.zip.ZipFile$1 pour zin (je ne connais même pas, ne sais pas à quoi cela correspond et m'attendais plutôt à un descendant de InputStream comme FileInputStream ou ZipFileInputStream ou ZipInputStream).
    C'est un descendant de InputStream. Un descendant qui n'a pas de nom. Si ce n'était pas un descendant de InputStream ça ne compilerait même pas et tu ne pourrais même pas essayer ton programme, sans même parler qu'il marche ou non.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  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 et pour l'explication sur java.util.zip.ZipFile$1.

    Voici le code où cela plante et ce que j'ai constaté pour dire que l'InputStream n'est pas le même:
    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
     
          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 isDone = false;
          while (!isDone) {
            inLength = sourceInputStream.read(inBytes);
            if (inLength == blockSize) {
              try {
                final int outLength =
                  cipher.update(inBytes, 0, blockSize, outBytes);
                destinationOutputStream.write(outBytes, 0, outLength);
              } catch (final ShortBufferException shortBufferException) {
                throw new IOException(shortBufferException);
              }
            } else {
              isDone = true;
            }
          }
     
          if (inLength > 0) {
            outBytes = cipher.doFinal(inBytes, 0, inLength);
          } else {
            outBytes = cipher.doFinal();
          }
          destinationOutputStream.write(outBytes);
    - Si j'extrait avec 7zip le fichier de mon jar puis que je le décrypte, inLength vaut -1 arrivé au if (inLength > 0) et passe donc dans le else. Je n'ai donc pas de problème.
    - Si j'obtiens mon InputStream avec le code donné dans mon premier message, les premiers blocs sont identiques mais arrivé au traitement du dernier bloc, le inLength vaut 13 au if (inLength > 0). Il passe donc dans le if et cela plante.

    Le comportement est donc identique pour les premiers blocs de 16 octets (qui sont identiques) mais différent pour le dernier bloc en fonction de si j'obtiens l'InputStream à partir du fichier décompréssé ou directement à partir du jar. C'est cela qui me fait pensé que l'InputStream est différent concernant le dernier bloc d'octets.

    Qu'est ce qui pourrait provoquer ce comportement (et cette différence pour le dernier bloc) et comment le corriger svp?
    Diplomes: DUT informatique et Master 2 MIAGE.
    Développeur Java/J2EE (principalement), .NET (niveau scolaire mais je compte m'améliorer ) et Web (HTML, PHP...).

  6. #6
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 554
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 554
    Points : 21 615
    Points
    21 615
    Par défaut
    InputStream.read() n'a pas de raison particulière de remplir entièrement le tableau que tu lui passes en paramètre. Il n'est pas surprenant qu'il le fasse si ça vient d'un fichier tout nu, mais en faisant du dézippage à la volée ce serait difficile.

    Par conséquent, tu n'as pas le droit de penser que la lecture est finie si le tableau n'a pas été entièrement rempli. La lecture est finie quand read() renvoie -1, et seulement dans ce cas.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  7. #7
    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
    Pourquoi la lecture se terminerait bien à -1 au moment où cela arrive au if (inLength > 0) avec l'InputStream issu du fichier dézippé et se termine à 13 au if (inLength > 0) avec l'InputStream issu directement à partir du jar?

    Voici le dernier bloc dans le premier cas où j'obiens -1 pour inLength:
    [1, 80, 93, 87, -72, 50, 107, 113, -67, 32, -15, -108, 41, -60, -112, 49]

    Voici le dernier bloc dans le second cas où j'obtiens 13:
    [1, 80, 93, 87, -72, 50, 107, 113, -67, 32, -15, -108, 41, 34, 69, -69]

    Le début est identique pour ce dernier bloc mais la fin ne l'est pas. Si l'InputStream doit contenir exactement la même chose cela devrait avoir le même compotement et être identique (je devrais obtenir -1 dans les 2 cas pour ce dernier bloc) non?
    Diplomes: DUT informatique et Master 2 MIAGE.
    Développeur Java/J2EE (principalement), .NET (niveau scolaire mais je compte m'améliorer ) et Web (HTML, PHP...).

  8. #8
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 554
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 554
    Points : 21 615
    Points
    21 615
    Par défaut
    Ce n'est pas pour jouer sur les mots. Certes les InputStream ne sont pas identiques, par contre ils fournissent un contenu identique. C'est évident que c'est pas les mêmes : il y en a un qui lit un fichier nu et l'autre qui extrait une entrée d'une archive zip.

    Ce qu'il faut retenir c'est que ta méthode de lecture était mauvaise. Le hasard et la chance faisait qu'au moment où tu testais sur ton ordinateur, le hasard produisait pile ce dont tu avais besoin, et du coup tu pensais que ça marche. Ce n'est pas le cas. Ça peut changer d'un ordinateur à l'autre et d'un jour à l'autre. read() n'est pas censé remplir le tableau que tu lui passes en paramètre, et la seule manière de savoir si la lecture est finie est d'attendre le -1, un point c'est tout.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  9. #9
    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
    Donc c'est l'algo (que j'avais trouvé sur ce forum d'ailleurs) qui n'est pas correct si je comprend ce que tu dis. Je pensais qu'il fallait lire par bloc de 16 octects puis appeler le cipher.update() sur ces blocs et que dès que le nombre d'octets est inférieur à 16, alors on termine le traitement en appelant cipher.doFinal() sur ce dernier bloc en lui précisant que cela va de 0 à inLength (ce qui semblait possible selon la doc de cipher et ce qui était fait dans le if (inLength > 0) ).

    Que me conseilles-tu de faire alors stp?
    Diplomes: DUT informatique et Master 2 MIAGE.
    Développeur Java/J2EE (principalement), .NET (niveau scolaire mais je compte m'améliorer ) et Web (HTML, PHP...).

  10. #10
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 554
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 554
    Points : 21 615
    Points
    21 615
    Par défaut
    Citation Envoyé par philou44300 Voir le message
    Donc c'est l'algo (que j'avais trouvé sur ce forum d'ailleurs) qui n'est pas correct si je comprend ce que tu dis.
    Ça c'est fort possible . Nos algos sont nettement moins testés que les bibliothèques Java. Si en plus tu pouvais nous dire où exactement, j'essaierais de faire corriger, ce serait extra.

    Citation Envoyé par philou44300 Voir le message
    Je pensais qu'il fallait lire par bloc de 16 octects puis appeler le cipher.update() sur ces blocs et que dès que le nombre d'octets est inférieur à 16, alors on termine le traitement en appelant cipher.doFinal() sur ce dernier bloc en lui précisant que cela va de 0 à inLength (ce qui semblait possible selon la doc de cipher et ce qui était fait dans le if (inLength > 0) ).
    Nope, il peut s'adapter à n'importe quelle quantité de données envoyées à la fois. C'est vrai que ce serait plus facile pour lui avec des blocs de la bonne taille, mais les flux ne fonctionnant pas comme ça, il est bien forcé de s'adapter, et donc n'est pas programmé pour tirer parti d'un alignement pile-poil. Il n'y a rien à y gagner.

    Citation Envoyé par philou44300 Voir le message
    Que me conseilles-tu de faire alors stp?
    Appeler update() en indiquant inLength à chaque fois, et à la fin appeler doFinal() sans paramètre.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  11. #11
    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
    Je vais essayer ca du coup et je viendrais faire un retour avec le bon algo (enfin j'espère ) . Il faut que je retrouve le topic où j'avais trouvé l'algo mais je sais qu'il était assez ancien^^.

    J'ai du coup une question, à quoi sert la méthode public final byte[] doFinal(byte[] input, int inputOffset, int inputLen)?

    Merci .
    Diplomes: DUT informatique et Master 2 MIAGE.
    Développeur Java/J2EE (principalement), .NET (niveau scolaire mais je compte m'améliorer ) et Web (HTML, PHP...).

  12. #12
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Citation Envoyé par philou44300 Voir le message
    P

    Voici le dernier bloc dans le premier cas où j'obiens -1 pour inLength:
    [1, 80, 93, 87, -72, 50, 107, 113, -67, 32, -15, -108, 41, -60, -112, 49]

    Voici le dernier bloc dans le second cas où j'obtiens 13:
    [1, 80, 93, 87, -72, 50, 107, 113, -67, 32, -15, -108, 41, 34, 69, -69]

    Le début est identique pour ce dernier bloc mais la fin ne l'est pas. Si l'InputStream doit contenir exactement la même chose cela devrait avoir le même compotement et être identique (je devrais obtenir -1 dans les 2 cas pour ce dernier bloc) non?
    Non, la fin différente n'est pas relevante. inputstream.read() te dit bien qu'il n'a lu que 13 bytes. Donc seuls les 13 bytes suivants sont relevant: [1, 80, 93, 87, -72, 50, 107, 113, -67, 32, -15, -108, 41, 34, 69, -69]

    Et si tu réappelle tout de suite read() , tu va voir que read te retournera "3" avec le contenu
    [-60, -112, 49, 87, -72, 50, 107, 113, -67, 32, -15, -108, 41, 34, 69, -69]

  13. #13
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 554
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 554
    Points : 21 615
    Points
    21 615
    Par défaut
    Citation Envoyé par philou44300 Voir le message
    J'ai du coup une question, à quoi sert la méthode public final byte[] doFinal(byte[] input, int inputOffset, int inputLen)?
    Je pense pas que ça soit transcendant. Elle fait double emploi avec le fait d'appeler update() d'abord et doFinal() sans paramètre quand on tout envoyé dans update(). Mais ça veut dire aussi qu'elle permet les deux actions en même temps au lieu de s'embêter à les appeler séparément.

    Par exemple si les données ne viennent pas d'un flux mais d'un tableau, dont on connaît donc déjà la taille totale et qu'on a entièrement à disposition, on peut faire d'abord update() de tout le tableau et doFinal() ensuite... Mais c'est pas pratique. Autant faire le doFinal() avec le tableau entier dès le début et ne jamais appeler update().
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  14. #14
    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
    Ok merci .

    En tout cas j'ai mis à jour mon algo et cela marche bien (en tout cas je n'ai pas relevé de problème pour le moment à part un problème avec le update en multi-thread mais je vais synchroniser tout ca car le update n'est pas thread-safe) . Le voici comme promis:
    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
     
          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 isDone = false;
          while (!isDone) {
            inLength = sourceInputStream.read(inBytes);
            if (inLength != -1) {
              // there is data in the stream to encrypt
              try {
                final int outLength =
                  cipher.update(inBytes, 0, inLength, outBytes);
                destinationOutputStream.write(outBytes, 0, outLength);
              } catch (final ShortBufferException shortBufferException) {
                throw new IOException(shortBufferException);
              }
            } else {
              // end of the stream to encrypt
              isDone = true;
            }
          }
     
          // do the final treatment
          outBytes = cipher.doFinal();
          destinationOutputStream.write(outBytes);
    Je vous remercie pour votre aide et vos réponses .
    Diplomes: DUT informatique et Master 2 MIAGE.
    Développeur Java/J2EE (principalement), .NET (niveau scolaire mais je compte m'améliorer ) et Web (HTML, PHP...).

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Accéder à un fichier XML depuis un jar
    Par Janitrix dans le forum Langage
    Réponses: 2
    Dernier message: 06/01/2007, 17h35
  2. Pb sur la methode waitFor depuis un jar
    Par martin_o dans le forum Général Java
    Réponses: 3
    Dernier message: 06/04/2006, 17h34
  3. [classpath]classpath non chargé depuis le jar, le système,..
    Par Grummfy dans le forum Général Java
    Réponses: 5
    Dernier message: 12/01/2006, 17h28
  4. getRessource() d'un fichier local depuis un JAR
    Par romaintaz dans le forum Entrée/Sortie
    Réponses: 2
    Dernier message: 03/08/2005, 12h11
  5. [JAR]ouverture de fichier texte depuis executables jar
    Par julien31 dans le forum Eclipse Java
    Réponses: 3
    Dernier message: 01/03/2005, 15h53

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