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:
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:
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:
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. |
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:
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:
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:
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