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

Hey,

Well, I got these two functions:
sub encryptFile { my $filename = shift; $| = 1; print "Encrypting $filename..."; $| = 0; my $cipher = Crypt::CBC->new( -key => $KEY, -cipher => 'Blowfish', -pad +ding => 'space', -add_header => 1 ); $cipher->start('encrypting'); open(ORGINAL, "<./$filename"); open(ENCRYPTED, ">./$filename.encrypted"); binmode ORGINAL; binmode ENCRYPTED; while (sysread(ORGINAL, my $buffer, 1024)) { syswrite(ENCRYPTED, $cipher->crypt($buffer)); } $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', -pad +ding => 'space', -add_header => 1 ); $cipher->start('decrypting'); open(ENCRYPTED, "<./$filename.encrypted"); open(DECRYPTED, ">./$filename"); binmode ENCRYPTED; binmode DECRYPTED; while (sysread(ENCRYPTED, my $buffer, 1024)) { syswrite(DECRYPTED, $cipher->crypt($buffer)); } $cipher->finish; close DECRYPTED; close ENCRYPTED; print "done.\n"; }
All seems fine and seems to be working. However, when I open the file I encrypted and then decrypted here, its not 100% as the original. I tested on a .zip file, and when reopening that, I get the structure in the .zip file, but I cant read any data (and extract it). Either the error is when creating the file, or its something with the decrypting process that Im missing. Usually this kind of error is when not using binary mode, but as you can see here I am. But still not working...

Anyone here that can spot the error?

Thanks,
Ace

Replies are listed 'Best First'.
Re: Something aint right using Crypt::CBC here...
by kaif (Friar) on Jun 21, 2005 at 05:48 UTC

    Take a look at the Crypt::CBC documentation carefully. Under the function finish, it says (emphasis mine)

    The CBC algorithm must buffer data blocks inernally until they are even multiples of the encryption algorithm's blocksize (typically 8 bytes). After the last call to crypt() you should call finish(). This flushes the internal buffer and returns any leftover ciphertext.

    To fix your problem, change your finish lines, respectively, to the following:

    syswrite( ENCRYPTED, $cipher->finish ); syswrite( DECRYPTED, $cipher->finish );

    Good luck! Thanks for your question. (Also, others will likely suggest other ways of doing your I/O --- consider using some of them.)

      Oh, ok, this was all I needed apparently. However, gonna look into the above aswell... Dont want any nasty bugs. :)
Re: Something aint right using Crypt::CBC here...
by Zaxo (Archbishop) on Jun 21, 2005 at 05:43 UTC

    I can't promise that this is the problem, but you don't check the results of sysread and syswrite. What happens if you get a short read and don't have a full block? The finish() method pads for that, but you can't use it in the midst of things.

    It would be easier to use buffered I/O with local $/ = \1024;. Your loops would then look like:

    { local ($/, $_) = \1024; while (<ENCRYPTED>)) { print DECRYPTED $cipher->crypt($_)); } $cipher->finish(); # amend to what kiaf says! }

    After Compline,
    Zaxo

Re: Something aint right using Crypt::CBC here...
by Ace128 (Hermit) on Jun 21, 2005 at 15:22 UTC
    Ok, I have another question consurning this module Crypt::CBC... How can i change the keysize to MORE than 56? DES uses 56 if Im not misstaken, and that is cracked. Doesnt really feel good using Blowfish and 56 bits key then! :)