crep has asked for the wisdom of the Perl Monks concerning the following question:

Hello masters of the art... I am rather new, sorry for my bad coding. Basically, all I want this script to do is output a blowfish encrypted file, then be able to make it text again. So far, it appears to run, but if I encrypt a file, then imediatly try to decrypt it with the same key, it doesn't work. I think the problem may be in the string parsing. Any ideas? blowfish.pl
use Crypt::Blowfish; #The key size can range from 32 bits (4 characters) to 448 bits (56 ch +aracters). system("clear"); #*nix system("cls"); #win print "Blowfish in perl. By jack (jack [at] crepinc.com)\n\n"; print "Enter key (4 to 56 characters): "; my $key_t = <STDIN>; chomp $key_t; my $key = pack("H16", $key_t); print "Encrypt or decrypt? ('e' or 'd'): "; my $func = <STDIN>; chomp $func; if ($func eq "e") { print "Enter file to encrypt: "; my $file = <STDIN>; chomp $file; open(fileIN, $file) or die("Can't open $file: $!"); @inFile = <fileIN>; close(fileIN); my $plaintex = ""; foreach $line (@inFile) { chomp($line); $plaintex = $plaintex.$line."\n"; } open(fileOUT, ">$file.enc") or die("Can't open $file.enc for writi +ng: $!"); my $cipher = new Crypt::Blowfish $key; #chomp $plaintex; my $len = length $plaintex; while ($len > 8) { $len -=8; } my $x = 8-$len; for ($x=0;$x<8-$len;$x++) { $plaintex = $plaintex." "; } my $len = length $plaintex; if ($len == 8) { my $ciphertext = $cipher->encrypt($plaintex); my $ciphertext = unpack("H16", $ciphertext); print fileOUT "$ciphertext"; } if ($len < 8) { $plaintex = $plaintex." "; $plaintex = substr ($plaintex,0,8); my $ciphertext = $cipher->encrypt($plaintex); my $ciphertext = unpack("H16", $ciphertext); print fileOUT "$ciphertext"; } if ($len > 8) { my $itmp = 0; for ($itmp=0; $itmp<$len; $itmp +=8) { $tmp = substr ($plaintex,$itmp,8); my $ciphertext = $cipher->encrypt($tmp); my $ciphertext = unpack("H16", $ciphertext); print fileOUT "$ciphertext"; } } close(fileOUT); print "Done.\n"; } if ($func eq "d") { print "Enter file to decrypt: "; my $file = <STDIN>; chomp $file; open(fileIN, $file) or die("Can't open $file: $!"); @inFile = <fileIN>; close(fileIN); my $ciphertext = ""; foreach $line (@inFile) { $ciphertext = "$ciphertext"."$line"."\n"; } my $filelen = length $file; my $ext = substr($file,$filelen-4,4); if ($ext eq ".enc") { $file = substr($file,0,$filelen-4); } open(fileOUT, ">$file") or die("Can't open $file for writing: $!") +; $ciphertext = substr($ciphertext,0,$len-1); my $len = length $ciphertext; print "len $len\n"; if ($len > 8) { my $itmp = 0; for ($itmp=0; $itmp<$len; $itmp +=16) { $tmp = substr ($ciphertext,$itmp,8); $tmp = pack("H16", $tmp); my $cipher = new Crypt::Blowfish $key; my $plaintext = $cipher->decrypt($tmp); print fileOUT "$plaintext"; } } if ($len < 9) { my $cipher = new Crypt::Blowfish $key; $ciphertextpack = pack("H16", $ciphertext); my $plaintext = $cipher->decrypt($ciphertextpack); print fileOUT "$plaintext"; } print "Done.\n"; }
Thanks VERY much, -Jack C jack@crepinc.com

Replies are listed 'Best First'.
Re: Blowfish Encryption problem
by beable (Friar) on Jul 14, 2004 at 02:15 UTC

    I think your main problem might be that you aren't using the Crypt::CBC module. Here is an example program which encrypts and decrypts a file using Blowfish:

    #!/usr/bin/perl use strict; use warnings; use Crypt::CBC; run(); sub run { my $cipher = Crypt::CBC->new( {'key' => 'my secret key +', 'cipher' => 'Blowfish', 'iv' => '$KJh#(}q', 'regenerate_key' => 0, # default + true 'padding' => 'space', 'prepend_iv' => 0, 'pcbc' => 1 #default 0 }); encrypt_and_decrypt_strings($cipher); encrypt_file($cipher); decrypt_file($cipher); } sub encrypt_and_decrypt_strings { my $cipher = shift; # encrypt and decrypt strings my $ciphertext = $cipher->encrypt("This data is hush hush"); my $plaintext = $cipher->decrypt($ciphertext); print("decrypted plaintext = $plaintext\n"); } sub encrypt_file { my $cipher = shift; print "encrypting file...\n"; my $plain_file = "BIG_FILE"; my $enc_file = "BIG_FILE.encrypted"; open OUTFILE, ">$enc_file" or die "can't open $enc_file: $!"; my $buffer; $cipher->start('encrypting'); open(F,"$plain_file") or die "can't open $plain_file: $!"; while (read(F, $buffer, 1024)) { print OUTFILE $cipher->crypt($buffer); } print OUTFILE $cipher->finish; close F; close OUTFILE; print "finished encrypting file\n"; } sub decrypt_file { my $cipher = shift; print "decrypting file...\n"; my $enc_file = "BIG_FILE.encrypted"; open INFILE, "<$enc_file" or die "can't open $enc_file: $!"; my $dec_file = "BIG_FILE.decrypted"; open DECFILE, ">$dec_file" or die "can't open $dec_file: $!"; $cipher->start('decrypting'); my $buffer; while (read(INFILE, $buffer, 1024)) { print DECFILE $cipher->crypt($buffer); } print DECFILE $cipher->finish; close DECFILE; close INFILE; print "finished decrypting file\n"; } __END__
Re: Blowfish Encryption problem
by pboin (Deacon) on Jul 14, 2004 at 14:52 UTC
    From the Crypt::Blowfish man page:

    In fact, if you have any intentions of encrypting more than eight bytes of data with this, or any other block cipher, you're going to need some type of block chaining help. Crypt::CBC tends to be very good at this. If you're not going to encrypt more than eight bytes, your data must be exactly eight bytes long.

    So, your data isn't encrypted properly. Crypt::Blowfish only does its work on eight bytes a time -- a block. It's just that you can't tell until you go to decrypt it.

    Crypt::CBC is a front-end to encryption modules that does the proper chaining, handles byte padding,etc. It's well documented.

      Thank you! Unfourtunatly for me I am stuck on a windows box for this particular project, so no man pages :(. But, once again, THANK YOU! -Jack C
        If perl is properly installed on your system, you should be able to do a perldoc Module::Name...

        thor