Reputation: 13
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:
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:
Upvotes: 1
Views: 454
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