[ Perl ] Créer sa propre DB de pass cryptée avec Blowfish
Par Deimos le 21-08-2005
Initiation aux modules cryptographiques en PERL
Sommaire :
I. Introduction
II. Installation des modules PERL sous Linux et Windows
II. 1. Sous Linux
II. 2. Sous Windows
III. Coding
I. Introduction
Perl a de nombreux modules, notamment des modules cryptographiques.
La quasi-totalité des cryptages à clé privée / publique et des
hashages sont disponibles en perl. Ce projet d'application permettra
de développer des notions de base en cryptographie et pourra peut
être en même temps avoir une utilité durant la vie courante.
En effet, le script que nous allons développer tout au long de cet
article vous servira à stocker vots mots de passe dans un fichier
texte crypté avec Blowfish mais également à rajouter des couples
login/pass dans ce fichier. Le rajout de ces couples aura pour
avantage de la possibilité de générer pour le compte en question une
chaine pseudo-aléatoire en guise de mot de passe. Ainsi notre script
pourra nous afficher le contenu du fichier crypté, sans jamais le
modifier et remplacer le texte chiffré par le texte clair, car cette
action pourrait laisser des traces sur un éventuel périphérique
comme un disque dur, une clé usb, etc.
En ce qui concerne l'algorithme de cryptage à clé privée, le choix
est rapidement fait en regardant les cryptages disponibles :
- DES est désormais considéré comme un algorithme "faible", en effet
sa clé a pour longueur 56 bits, ce qui est facilement cassable par
une attaque brute force avec la technologie moderne.
- TripleDES est donc le chiffrement par bloc qui est venu remplacé
le standard DES : il permet de crypter avec une clé de longueur
comprise entre 128 et 192 bits.
- AES et Blowfish sont aujourd'hui des chiffrements à clé secrète
dits "forts" et l'un d'eux fait donc parfaitement l'affaire pour le
genre d'opération que nous souhaitons faire. AES permet une longueur
de clé de 128,192 ou 256 bits et Blowfish entre 32 et 448 bits. AES
est cependant plus rapide, mais avec un simple fichier texte content
des mots de passe qui n'excèdera pas souvent 100Ko, autant prendre
Blowfish.
Pour une meilleure portabilité, les modules utilisés fonctionnent
sous OS Unix et Windows.
II. Installation des modules PERL sous Linux et Windows
Nous aurons besoin pour la réalisation de notre script, des modules
suivants :
- Crypt::CBC pour obtenir la cryptographie par bloc (Cipher Block
Chaining Mode)
- String::Random pour pouvoir générer des chaines pseudo-aléatoires
- Term::ReadKey pour masquer la saisie des caractères lors de
l'entrée de la clé.
Je ne décrirais pas comment utiliser les modules, car leur
utilisation est clairement expliquée sur le site de CPAN, avec
exemples.
1. Sous Linux
Si vous êtes l'heureux possésseur d'une distribution Linux, ce sera
simple. Premièrement, testez si le module n'est pas déjà présent en
effectuant la commande suivante ( en prenant comme exemple le module
Crypt::CBC ) :
| Code: | |
| $ perl -e 'use Crypt::CBC' |
| Code: | |
|
gunzip -d Crypt-CBC-2.15.tar.gzip tar -xvj Crypt-CBC-2.15.tar OU tar -zxvf Crypt-CBC-2.15.tar.gz cd Crypt-CBC-2.15 perl Makefile.pl make make test su make install |
| Code: | |
|
C:\>ppm ppm> search Term ppm> install TermReadKey ppm> search String ppm> install String-Random |
| Code: | |
|
C:\>perl -v |
| Code: | |
|
ppm install http://theoryx5.uwinnipeg.ca/ppms/Crypt-CBC.ppd ou ppm install http://theoryx5.uwinnipeg.ca/ppmpackages/Crypt-CBC.ppd |
| Code: | |
| #!usr/bin/perl use Crypt::CBC; use String::Random; use Term::ReadKey; |
| Code: | |
| print "Hi, welcome to passwords' manager coded
by Deimos.\n". "This script encrypts and decrypts passwords' database who\n". "is encrypted whit Blowfish.\r\n"; print "> Please Enter Blowfish Key"; print "\r\n> "; |
| Code: | |
| ReadMode 2; my $key = c; chomp $key; |
| Code: | |
| while($key eq "") { print "\r\n> "; $key = <STDIN>; chomp $key; } |
| Code: | |
| ReadMode 0; |
| Code: | |
| my $blowfish = Crypt::CBC -> new(-key => $key,
-cipher => "Blowfish", -padding => "null"); |
| Code: | |
| print "\r\n> Please enter a command - use
'help' to get the ". "list of available commands\r\n" |
| Code: | |
| while(1) { |
| Code: | |
| print "> "; $comm = <STDIN>; chomp $comm; |
| Code: | |
| if($comm =~ /^HELP/i) { print "\r\nList of available commands :\r\n". "HELP - Screen this plaintext\r\n". "SCREEN - Decrypt & Screen the DB of passwords\r\n". "ADD - Allow to add passwords on the DB with\r\n". " possibility of pseudo-random strings gen\r\n"; } |
| Code: | |
| elsif($comm =~ /^SCREEN/i) { open(OUTFILE,"pass.txt"); my @out = <OUTFILE>; close(OUTFILE); my $ciphertext = "@out"; my $plaintext = $blowfish -> decrypt($ciphertext); print $plaintext; } |
| Code: | |
| elsif($comm =~ /^ADD/i) { print "> Enter username : "; my $username = <STDIN>; chomp $username; print "> Would you like generate pseudo-random password ? [y\\n]"; my $answer = <STDIN>; chomp $answer; |
| Code: | |
| if($answer =~ /^y$/i) { my $random = new String::Random; $size = $random -> randregex("1[0-5]"); print "> Can the password contain special ". "characters ? [y\\n]"; my $answer2 = <STDIN>; chomp $answer2; unless($answer2 =~ /^y|n$/i) { print "> Can the password contain ". "special characters ? [y\\n]"; $answer2 = <STDIN>; chomp $answer2; } if($answer2 =~ /^y$/i) { $pass = $random -> randregex("."); } elsif($answer2 =~ /^n$/i) { $pass = $random -> randregex("[a-zA-Z0-9]"); } } elsif($answer =~ /^n$/i) { print "> Enter a password for your new account : "; ReadMode 2; $pass = <STDIN>; ReadMode 0; chomp $pass; print "\r\n"; } |
| Code: | |
| print "> Enter description for your new
account (optional) : "; my $desc = <STDIN>; chomp $desc; |
| Code: | |
| open(OUTFILE,"pass.txt"); @out = <OUTFILE>; close(OUTFILE); $ciphertext = "@out"; my $addtext = "$username - $pass\r\n$desc\r\n\r\n"; my $plaintext = $blowfish -> decrypt($ciphertext); my $newtext = $plaintext . $addtext; |
| Code: | |
| my $newciphertext = $blowfish -> encrypt($newtext);
open(INFILE,">pass.txt"); print INFILE $newciphertext; close(INFILE); |
| Code: | |
| >use Crypt::CBC; #page 10 RFC 792 Internet Control Message Protocol $key = "This checksum may be replaced in the future."; my $blowfish = Crypt::CBC -> new(-key => $key, -cipher => "Blowfish", -padding => "null"); $text = "Welcome to passwords' database ;)\r\n\r\n"; $cipher = $blowfish -> encrypt($text); $plaintext = $blowfish -> decrypt($cipher); open(FILE,">pass.txt"); print FILE $cipher; close(FILE); |