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

Modules Perl Discussion :

Problème de chiffrage/déchiffrage avec le module Crypt::CBC


Sujet :

Modules Perl

  1. #1
    Membre du Club
    Profil pro
    Développeur Full Stack
    Inscrit en
    Novembre 2007
    Messages
    101
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Full Stack

    Informations forums :
    Inscription : Novembre 2007
    Messages : 101
    Points : 52
    Points
    52
    Par défaut Problème de chiffrage/déchiffrage avec le module Crypt::CBC
    Bonjour,

    Je rencontre un problème en utilisant le module de chiffrage Crypt::CBC avec un exemple simple que j'ai pris dans le livre "Les meilleurs bibliothèques pour Perl", (Editions H&K), pages 99-100.

    J'ai seulement écrit les codes pour le chiffrage et le déchiffrage dans 2 scripts séparés.

    Le principe est le suivant, on crypte chaque ligne du fichier clair.txt, que l'on écrit dans le fichier crypt.txt, avec le premier script.

    Puis, avec le second script on fait l'opération inverse, en écrivant les données décryptées dans le nouveau fichier clair_2.txt, pour comparer.

    Lors du décryptage on a l'erreur suivante :

    "Ciphertext does not begin with a valid header for 'salt' header mode at decrypte.pl line 13"

    Quelqu'un a-t-il une idée sur l'origine de ce problème ? Et la solution ?

    Merci.

    Code du script crypte.pl :
    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
    #!/usr/bin/perl -w
    use strict;
    use warnings;
    use Crypt::CBC;
     
    my $crypt = new Crypt::CBC('passwd');
    open CLAIR, "clair.txt" or die $!;
    open CRYPT, ">crypt.txt" or die $!;
    $crypt->start('encrypting');
    while(<CLAIR>) {
        print CRYPT $crypt->crypt($_);
    }
     
    print CRYPT $crypt->finish();
    close CLAIR;
    close CRYPT;
    Code du script decrypte.pl :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #!/usr/bin/perl -w
    use strict;
    use warnings;
    use Crypt::CBC;
     
    my $crypt = new Crypt::CBC('passwd');
    open CRYPT, "crypt.txt" or die $!;
    open CLAIR, ">clair_2.txt" or die $!;
    $crypt->start('decrypting');
    while(<CRYPT>) {
        print CLAIR $crypt->decrypt($_);
    }
    close CLAIR;
    close CRYPT;
    Contenu du fichier clair.txt :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Ceci est un test de chiffrage de fichier avec le module Crypt::CBC.
    Ceci est un test de chiffrage de fichier avec le module Crypt::CBC.
    Ceci est un test de chiffrage de fichier avec le module Crypt::CBC.
    Ceci est un test de chiffrage de fichier avec le module Crypt::CBC.

  2. #2
    Membre du Club
    Profil pro
    Développeur Full Stack
    Inscrit en
    Novembre 2007
    Messages
    101
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Full Stack

    Informations forums :
    Inscription : Novembre 2007
    Messages : 101
    Points : 52
    Points
    52
    Par défaut J'ai fini par utiliser le module Crypt::Blowfish
    J'ai trouvé une autre solution :

    Mon but n'était pas d'utiliser systématiquement le module Crypt::CBC. Les premières recherches concernant le cryptage m'ont orienté vers ce module. Visiblement, il semble un peu compliqué à utiliser, en ce qui concerne le paramétrage, et nécessite je suppose de bonnes connaissances en cryptographie.

    Je me suis rabattu vers le module Crypt::Blowfish, plus simple à mettre en oeuvre.

    Toujours sur le même principe, le 1er script crypte le fichier 'clair.txt', et le second effectue l'opération inverse.

    Le seul soucis, d'après ce que j'ai compris, c'est que la clé doit faire au minimum 8 octets, et que le fichier est crypté par bloc de données de taille constante. Or, lorsqu'on lit le fichier à cryter ligne par ligne, on n'a pas un nombre de données constant.

    Pour régler ce problème, on modifie la façon de lire le fichier, en effectuant une lecture par bloc, grâce à la variable spéciale $/.
    Cette variable contient le séparateur d'enregistrement, qui vaut par défaut '\n' (lecture du fichier ligne par ligne).

    Si on lui affecte une référence à un nombre, comme ici 8, la lecture du fichier se fait alors par blocs de 8 octets.
    La chaîne de 8 octets ainsi récupérée est cryptée avec la méthode encrypt, et on l'ajoute à la variable $cryptage.

    Le problème est que la taille du fichier (en octets) n'est pas forcément un multiple de 8, et dans ce cas, le dernier bloc lu aura une longueur inférieure à 8. Dans ce cas, l'astuce que j'ai trouvée est de compléter la chaîne par un ou plusieurs caractères 'exotiques' (joker), de façon à obtenir une chaîne de 8 octets et de pouvoir la crypter comme les précédentes.

    Remarque 1 : par caractère 'exotique' j'entends un caractère peu utilisé et qui a peu de risque d'être présent dans le fichier à crypter.

    Remarque : pour éviter des surprises, on modifie la variable $/ de façon locale !

    Cette opération correspond aux lignes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    {
        local $/ = \$block_length;      # On modifie localement la valeur du séparateur d'enregistrement
        while(my $block = <CLAIR>) {                       
            my $L = length $block;
            if($L < $block_length) {
                my $d = $block_length - $L;                
                $block .= $jocker x $d; # Si le dernier bloc du fichier est inférieur à $block_length, on complète avec un caractère 'exotique'
            }
            $cryptage .= $crypt->encrypt($block); # On ajoute la chaîne cryptée à $cryptage !
    }
    Pour le décryptage, on effectue l'opération inverse, en ne perdant pas de vue que l'on va éventuellement récupérer en fin de fichier, les jokers ajoutés lors du cryptage, et qu'il faut donc les supprimer avant d'écrire le contenu du fichier décrypté.

    Je pense que cette astuce que j'ai trouvée n'est pas la meilleure façon de faire en matière de cryptologie, donc, avis aux spécialistes !

    Code du script crypte.pl
    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
    #!/usr/bin/perl -w
    use strict;
    use warnings;
    use Crypt::Blowfish;
     
    my $key ='a1b2c3d4'; # Par exemple
    my $block_length = 8;
    my $jocker = '¤';
     
    my $crypt = new Crypt::Blowfish $key;
    open(CLAIR, '<', 'clair.txt'); 
    my $cryptage = '';
    { 
        local $/ = \$block_length;      # On modifie localement la valeur du séparateur d'enregistrement
        while(my $block = <CLAIR>) {                       
            my $L = length $block;
            if($L < $block_length) {
                my $d = $block_length - $L;                
                $block .= $jocker x $d; # Si le dernier bloc du fichier est inférieur à $block_length, on complète avec un caractère 'exotique'
            }
            $cryptage .= $crypt->encrypt($block); # On ajoute la chaîne cryptée à $cryptage !
        }
    }
    close CLAIR;
     
    # On écrit le contenu crypté dans un fichier    
    open CRYPT, ">crypt.txt" or die $!;
    print CRYPT $cryptage;
    close CRYPT;


    Code du script decrypte.pl
    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
    #!/usr/bin/perl -w
    use strict;
    use warnings;
    use Crypt::Blowfish;
     
    my $key ='a1b2c3d4';
    my $block_length = 8;
    my $jocker = '¤';
     
    my $crypt = new Crypt::Blowfish $key;
    open(CRYPT, '<', 'crypt.txt'); 
    my $clair = '';
    { 
        local $/ = \$block_length;      # On modifie localement la valeur du séparateur d'enregistrement
        while(my $block = <CRYPT>) {                                   
            $clair .= $crypt->decrypt($block); # On ajoute la chaîne decryptée à $cryptage !
        }
    }
    close CRYPT;
     
    # On supprime les caractères 'exotiques' ajoutés en fin de fichier lors du cryptage
    $clair =~ s/($jocker+)$//;
     
    # On écrit le contenu crypté dans un fichier    
    open CLAIR, ">crypt_clair.txt" or die $!;
    print CLAIR $clair;
    close CLAIR;
    Je ne suis pas un expert du cryptage, alors toutes les remarques constructives qui pourront servir à d'autres sont les bienvenues.

    Krys006

  3. #3
    Membre du Club
    Homme Profil pro
    Inscrit en
    Février 2009
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2009
    Messages : 37
    Points : 40
    Points
    40
    Par défaut
    Bonjour,

    Pour ta première solution, est-ce que tu as essayé en indiquant que tu n'avais pas de header ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    my $crypt = Crypt::CBC->new(-key => 'passwd', -header => 'none');
    Voir le CPAN pour le détail: Crypt::CBC

    Sinon par sécurité j'aurai tendance à lire un fichier crypté en forçant le mode binaire...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    ...
    open CRYPT, "crypt.txt" or die $!;
    ...
    binmode(CRYPT);
    ...
    Pour ton second post, je sais que j'ai déjà fait du complement de buffer pour un usage similaire (sur du MD5 il me semble), le temps de retrouver le code pour te fournir un exemple....

  4. #4
    Membre du Club
    Homme Profil pro
    Inscrit en
    Février 2009
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2009
    Messages : 37
    Points : 40
    Points
    40
    Par défaut
    Bon, en fait de MD5 c'était RC5 le module que j'ai utilisé (beaucoup plus rudimentaire).

    Le code qui encrypte une chaîne:

    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
    use strict;
    use Crypt::RC5;
     
    my $KEY = 'maclef';
    my $ROUNDS = "12";
    my $CRYPT = Crypt::RC5->new($KEY,$ROUNDS);
     
    print "Texte a crypter: ";
    my $BUFFER = <STDIN>;
    chomp($BUFFER);
     
    open (CRYPTED,"> ./mon_texte.crypt") or die ("Erreur: $!");
    binmode(CRYPTED);
    print CRYPTED $CRYPT->encrypt($BUFFER);
    close(CRYPTED);
     
    print "Fini\n";
     
    exit 0;

    Celui qui décrypte:

    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
    use strict;
    use Crypt::RC5;
     
    my $KEY = 'maclef';
    my $ROUNDS = "12";
    my $CRYPT = Crypt::RC5->new($KEY,$ROUNDS);
     
    open (CRYPTED,"< ./mon_texte.crypt") or die ("Erreur: $!");
    binmode(CRYPTED);
    my $BUFFER = <CRYPTED>;
    close(CRYPTED);
     
    print $CRYPT->decrypt($BUFFER) . "\n";
     
    exit 0;
    En espérant que cela t'aide....

  5. #5
    Membre du Club
    Profil pro
    Développeur Full Stack
    Inscrit en
    Novembre 2007
    Messages
    101
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Full Stack

    Informations forums :
    Inscription : Novembre 2007
    Messages : 101
    Points : 52
    Points
    52
    Par défaut
    Pour ta première solution, est-ce que tu as essayé en indiquant que tu n'avais pas de header ?
    Oui, c'est la première chose que j'ai faite après un coup d'oeil sur la doc du cpan. Mais ça ne change rien.

    Sinon par sécurité j'aurai tendance à lire un fichier crypté en forçant le mode binaire...
    Est-ce que tu peux préciser le risque encouru à ne pas faire celà ?

    Bon, en fait de MD5 c'était RC5 le module que j'ai utilisé (beaucoup plus rudimentaire).

    Le code qui encrypte une chaîne:
    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
    use strict;
    use Crypt::RC5;
     
    my $KEY = 'maclef';
    my $ROUNDS = "12";
    my $CRYPT = Crypt::RC5->new($KEY,$ROUNDS);
     
    print "Texte a crypter: ";
    my $BUFFER = <STDIN>;
    chomp($BUFFER);
     
    open (CRYPTED,"> ./mon_texte.crypt") or die ("Erreur: $!");
    binmode(CRYPTED);
    print CRYPTED $CRYPT->encrypt($BUFFER);
    close(CRYPTED);
     
    print "Fini\n";
     
    exit 0;
    Tu peux m'expliquer le rôle de la variable $ROUNDS.

    Désolé pour ma réponse tardive.
    Je vais prendre en compte ton exemple.
    Merci pour l'intérêt porté à ce post. J'espère que tes précisions serviront à d'autres.

    Krys006

  6. #6
    Membre du Club
    Homme Profil pro
    Inscrit en
    Février 2009
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2009
    Messages : 37
    Points : 40
    Points
    40
    Par défaut
    De mémoire c'est un algo qui travaille par bloc avec un XOR quelque part et l'ensemble est ré-itéré $ROUND fois avant de fournir un résultat (quel que soit le sens). Un nombre d'itération à 12 est le minimum recommandé dans la doc du module (pour un bon ratio performance/sécurité j'imagine). Je n'ai pas fait beaucoup de recherches à l'époque, il y a surement de la littérature en ligne.

    Pour la lecture en mode binaire, cela évite en principe tout effet d'encodage qui pourrait survenir avec une lecture du contenu encrypté. Je n'ai jamais eu beaucoup de certitudes sur la façon dont perl lisait par défaut un contenu via un filehandler....

    Sinon tout pareil: désolé de revenir sur le sujet si tardivement...

Discussions similaires

  1. probléme de démarrage vista avec le module HPQWMIEX a cessé de fonctionner?
    Par lalouvesijetattrape dans le forum Windows Vista
    Réponses: 3
    Dernier message: 24/06/2008, 18h32
  2. pb avec le module Crypt-DES-2.05
    Par super_dz dans le forum Modules
    Réponses: 6
    Dernier message: 10/09/2007, 15h49
  3. [Système] Problème avec la fonction crypt()
    Par Jérémy51 dans le forum Langage
    Réponses: 5
    Dernier message: 28/10/2006, 12h42
  4. problème avec le module DBI
    Par vbcasimir dans le forum SGBD
    Réponses: 6
    Dernier message: 08/10/2005, 12h48
  5. problème avec un module
    Par vbcasimir dans le forum Modules
    Réponses: 2
    Dernier message: 29/08/2005, 15h59

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