En/Decryption 使用 Perl Crypt::CBC 导致最后缺少字节

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

我正在尝试在 perl 中使用 Crypt::CBC 加密然后解密文件。加密后解密我的密文时,我在恢复的明文末尾丢失了一些字节。

加密方式:

#!/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;

我的明文是这样的:

然后我解密我的密文:

#!/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;

以及之后的明文:

您在循环后缺少对 $cipher->finish; 的调用,用于加密和解密,因此在这两种情况下您都削减了最后一个块的一部分。

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.

你需要这样的东西:

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

(您的解密代码中 open 行末尾还缺少一个分号。)