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

I'm on linux and using perl5.8.7, with the latest versions of both modules. This script used to run fine, last time I checked (maybe a year ago). But someone asked a question on the perl.crypto maillist, about experiencing corruption with Crypt::CBC and Crypt::Blowfish. So I tested my sample script again, and there was corruption in the output. Here is the script. It encrypts and decrypts itself.
#!/usr/bin/perl use warnings; use strict; use Crypt::CBC; ##----------- encryption ------------ my $cipher = Crypt::CBC->new( {'key' => 'secretfoo', 'cipher' => 'Blowfish', 'padding' => 'standard', }); open(INF, "< $0" ) || die; open(OUTF, ">$0.crypt") || die; $cipher->start('encrypting'); while (read(INF,my $buf, 1024 ) ) { print OUTF $cipher->crypt($buf); } print OUTF $cipher->finish; close(INF); close(OUTF); ##-------------------------- decryption -------------------- my $cipher1 = Crypt::CBC->new( {'key' => 'secretfoo', 'cipher' => 'Blowfish', 'padding' => 'standard', }); open (INF1, "< $0.crypt") || die; open (OUTF1, ">$0.decrypt") || die; $cipher->start('decrypting'); while (read(INF1,my $buf, 1024 ) ) { print OUTF1 $cipher->decrypt($buf); } print OUTF1 $cipher->finish; close(INF1); close(OUTF1); __END__

###############################################

and the corruption in the decoded output

#### ........... ........... while (read(INF1,my $buf, 1024 ) ) { print OUTF1 $cipher->decrypt($buf); } pri.<d^KOb.Ï->finish; close(INF1); close(OUTF1);
I figure it is probably something simple, but I can't figure out what it is.

I'm not really a human, but I play one on earth. flash japh

Replies are listed 'Best First'.
Re: Crypt::CBC with Blowfish problem
by tirwhan (Abbot) on Jan 06, 2006 at 15:23 UTC

    If you slurp the encrypted data in and decrypt the whole string in one go it does not corrupt:

    open(INF1, "<", "$0.crypt") || die; open(OUTF1, ">$0.decrypt") || die; local $/=undef; my $in = <INF1>; print OUTF1 $cipher->decrypt($in); close(INF1); close(OUTF1);

    There are ten types of people: those that understand binary and those that don't.
      Thanks for pointing that out. I also found a workable snippet at Something aint right using Crypt::CBC here....
      #!/usr/bin/perl use warnings; use strict; use Crypt::CBC; my $KEY = 'secret_foo'; encryptFile( $0 ); decryptFile( "$0.enc"); sub encryptFile { my $filename = shift; $| = 1; print "Encrypting $filename..."; $| = 0; my $cipher = Crypt::CBC->new( -key => $KEY, -cipher => 'Blowfish', -padding => 'space', -add_header => 1 ); $cipher->start( 'encrypting' ); open( ORGINAL, "<./$filename" ); open( ENCRYPTED, ">./$filename.enc" ); binmode ORGINAL; binmode ENCRYPTED; while ( sysread( ORGINAL, my $buffer, 1024 ) ) { syswrite( ENCRYPTED, $cipher->crypt( $buffer ) ); } #$cipher->finish; #wrong syswrite( ENCRYPTED, $cipher->finish ); close ENCRYPTED; close ORGINAL; print "done.\n"; } ################################################################### sub decryptFile { my $filename = shift; $| = 1; print "Decrypting $filename..."; $| = 0; my $cipher = Crypt::CBC->new( -key => $KEY, -cipher => 'Blowfish', -padding => 'space', -add_header => 1 ); $cipher->start( 'decrypting' ); open( ENCRYPTED, "<./$filename" ); open( DECRYPTED, ">./$filename.decrypted" ); binmode ENCRYPTED; binmode DECRYPTED; while ( sysread( ENCRYPTED, my $buffer, 1024 ) ) { syswrite( DECRYPTED, $cipher->crypt( $buffer ) ); } # $cipher->finish; #wrong syswrite( DECRYPTED, $cipher->finish ); close DECRYPTED; close ENCRYPTED; print "done.\n"; }

      I'm not really a human, but I play one on earth. flash japh
Re: Crypt::CBC with Blowfish problem
by borisz (Canon) on Jan 06, 2006 at 15:45 UTC
    use binmode on your filehandles. ie:
    open(INF, "< $0" ) || die; binmode INF; open(OUTF, ">$0.crypt") || die; binmode OUTF;
    Boris
Re: Crypt::CBC with Blowfish problem
by zentara (Cardinal) on Jan 06, 2006 at 15:05 UTC
    I have another sample which uses $iv, and dosn't corrupt, but it leaves an extra few letters on the last line after decypting.
    #!/usr/bin/perl use warnings; use strict; use Crypt::CBC; my $iv = '$KJ^#(}q'; my $key = 'secret_foo'; ##----------- encryption ------------ my $cipher = Crypt::CBC->new( { 'key' => $key, 'cipher' => 'Blowfish', 'padding' => 'standard', 'iv' => $iv } ); open( INF, "< $0" ) || die; open( OUTF, ">$0.crypt" ) || die; $cipher->start('encrypting'); while ( read( INF, my $buf, 1024 ) ) { print OUTF $cipher->crypt($buf); } print OUTF $cipher->finish; close(INF); close(OUTF); ##-------------------------- decryption -------------------- my $cipher1 = Crypt::CBC->new( { 'key' => $key, 'cipher' => 'Blowfish', 'padding' => 'standard', 'iv' => $iv } ); open( INF1, "< $0.crypt" ) || die; open( OUTF1, ">$0.decrypt" ) || die; $cipher->start('decrypting'); while ( read( INF1, my $buf, 1024 ) ) { print OUTF1 $cipher->decrypt($buf); } print OUTF1 $cipher->finish; close(INF1); close(OUTF1);

    I'm not really a human, but I play one on earth. flash japh
Re: Crypt::CBC with Blowfish problem
by reneeb (Chaplain) on Jan 07, 2006 at 07:42 UTC