使用Perl Crypt :: CBC进行En / Decryption导致最后丢失字节

时间:2017-07-24 12:05:12

标签: perl encryption file-handling des

我正在尝试使用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;

我的明文看起来像这样:

plaintext before

然后我解密我的密文:

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

以及之后的明文:

plaintext after

1 个答案:

答案 0 :(得分:2)

对于加密和解密,你在循环之后错过了对$cipher->finish;的调用,因此在两种情况下你都会删除最后一个块的一部分。

  

CBC算法必须在内部缓冲数据块,直到它们是加密算法的块大小(通常是8个字节)的倍数。在最后一次调用crypt()之后,你应该调用finish()。这会刷新内部缓冲区并返回任何剩余的密文。

你需要这样的东西:

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

(您还在解密代码的open行末尾错过了分号。)