ichtyp
ichtyp

Reputation: 13

En/Decryption using Perl Crypt::CBC leads to missing bytes at the end

i am trying to encrypt and then decrypt a file using Crypt::CBC in perl. When decrypting my ciphertext after encrypting it, i am missing some bytes at the end of my recovered plaintext.

encryption method:

#!/usr/bin/perl

use 5.24.0;
use warnings;
use Crypt::CBC;

my $cipher;
my $buffer;

   $cipher = Crypt::CBC->new( {'key'             => 'abcdefgh',
                               'literal_key'     => 1, 
                     # 'cipher'          => 'Blowfish',
                              'iv'              => '01234567',
                           #   'regenerate_key'  => 0,   # default true
                              'padding'         => 'standard',
                              'prepend_iv'      => 0,
                              'blocksize'       => 8
                           });

$cipher->start('encrypting');
open(F,"./plaintext.txt");
open(STDOUT,">ciphertext.txt");
  while (sysread(F,$buffer,1024)) {
      print $cipher->crypt($buffer);
  }
close STDOUT;

my plaintext looks like this:

plaintext before

then i decrypt my ciphertext with:

#!/usr/bin/perl
# # entschlüsselt eine datei, http://www.perlmonks.org/?node_id=252460

use 5.24.0;
use warnings;
use Crypt::CBC;

my $cipher;
my $buffer;

   $cipher = Crypt::CBC->new( {'key'             => 'abcdefgh',
                              'literal_key'     => 1, 
                              #'cipher'          => 'Blowfish',
                              'iv'              => '01234567',
                            #  'regenerate_key'  => 0,   # default true
                              'padding'         => 'standard',
                              'prepend_iv'      => 0,
                              'blocksize'       => 8
                           });

$cipher->start('decrypting');
open(F,"./ciphertext.txt")
  while (sysread(F,$buffer,1024)) {
      print $cipher->crypt($buffer);

  }
close STDOUT;

and the plaintext afterwards:

plaintext after

Upvotes: 1

Views: 454

Answers (1)

matt
matt

Reputation: 79743

You’re missing a call to $cipher->finish; after the loop, for both encrypting and decrypting, so you’re cutting of part of the last block in both cases.

The CBC algorithm must buffer data blocks internally 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.

You need something like this:

while (sysread(F,$buffer,1024)) {
    print $cipher->crypt($buffer);
}
print $cipher->finish;

(You’re also missing a semicolon at the end of the open line in your decryption code.)

Upvotes: 2

Related Questions