【问题标题】:En/Decryption using Perl Crypt::CBC leads to missing bytes at the end使用 Perl Crypt::CBC 进行加密/解密会导致最后丢失字节
【发布时间】:2017-07-24 12:05:12
【问题描述】:

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

以及之后的明文:

【问题讨论】:

  • 像这样重新打开 STDOUT 是一种奇怪的做法。您可以尝试打开一个单独的非默认文件句柄吗?我想知道这样做是否会导致它不像你期望的那样被刷新。
  • 虽然它在这种特殊情况下可能没有效果,但您希望使用 :raw 句柄完成与 ciphertext.txt 的交互,因为它是“二进制”文件,而不是文本文件(尽管扩展名)。
  • 提示:使用常量 IV 是不负责任并且严重会削弱您的加密。让 CBC 随机选择一个!
  • ... 并将 IV 作为密文的前缀(它具有恒定的大小)。但这是上面代码的第四个问题,我猜你(ichtyp)需要在继续之前阅读更多关于文件处理和加密的内容。
  • @frezik:我现在使用一个单独的文件处理程序,它帮助我摆脱了行尾的 CR LF 格式问题。

标签: perl encryption file-handling des


【解决方案1】:

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

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

你需要这样的东西:

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

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

【讨论】:

  • 绝对正确。但是,我想(很大程度上)忽略sysread 调用的返回值是一个更大的问题。
  • 就是这样!非常感谢 :-) 缺少的分号在 c&p 上丢失了。忽略返回值不是目标,我只是想正确获取文件的内容。我现在会继续这个。无论如何感谢您的提示!
猜你喜欢
  • 2014-03-21
  • 1970-01-01
  • 1970-01-01
  • 2023-03-03
  • 1970-01-01
  • 2010-10-13
  • 2015-11-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多