2017-05-27 71 views
2

我试图使用chilkat功能测试文件加密。基于对this例如页面发现的代码,我替换为最后一部分:奇尔卡特加密不能按预期工作

# Encrypt a string... 
# The input string is 44 ANSI characters (i.e. 44 bytes), so 
# the output should be 48 bytes (a multiple of 16). 
# Because the output is a hex string, it should 
# be 96 characters long (2 chars per byte). 


my $input = "sample.pdf"; 
# create file handle for the pdf file 
open my $fh, '<', $input or die $!; 
binmode ($fh); 

# the output should be sample.pdf.enc.dec 
open my $ffh, '>', "$input.enc.dec" or die $!; 
binmode $ffh; 

my $encStr; 
# read 16 bytes at a time 
while (read($fh,my $block,16)) { 
    # encrypt the 16 bytes block using encryptStringEnc sub provided by chilkat 
    $encStr = $crypt->encryptStringENC($block); 
    # Now decrypt: 
    # decrypt the encrypted block 
    my $decStr = $crypt->decryptStringENC($encStr); 
    # print it in the sample.pdf.enc.dec file 
    print $ffh $decStr; 
} 
close $fh; 
close $ffh; 

免责声明: 我知道,不建议文件加密CBC模式,因为如果一个块丢失,其他块丢失太。 输出文件已损坏,当我在两个文件中进行超越比较时,出现了匹配的文件块,并且没有文件块。我究竟做错了什么?

+0

如果不知道'$ crypt'是什么类型的对象,我们就无法得到任何帮助。它是如何创建的? –

+0

@DaveCross快速搜索显示它是 - * fck这个,让我们在一个类中完成 - * [CkCrypt2](https://www.chilkatsoft.com/refdoc/vcCkCrypt2Doc.html)组件。 –

+2

@MaartenBodewes:我想你的意思是链接到[Perl模块](https://www.chilkatsoft.com/refdoc/perlCkCrypt2Ref.html)而不是C++。但我的观点是,我们不应该需要做这种搜索。 –

回答

3

您正在尝试使用字符串什么是加密(encryptStringENC()decryptStringENC()),至少部分,一个二进制文件。

这为我工作:

my $input = "sample.pdf"; 
# create file handle for the pdf file 
open my $fh, '<', $input or die $!; 
binmode $fh; 

# the output should be sample.pdf.enc.dec 
open my $ffh, '>', "$input.enc.dec" or die $!; 
binmode $ffh; 

my $inData = chilkat::CkByteData->new; 
my $encData = chilkat::CkByteData->new; 
my $outData = chilkat::CkByteData->new; 

# read 16 bytes at a time 
while (my $len = read($fh, my $block, 16)) { 

    $inData->clear; 
    $inData->append2($block, $len); 

    $crypt->EncryptBytes($inData, $encData); 
    $crypt->DecryptBytes($encData, $outData); 

    print $ffh $outData->getData; 
} 

close $fh; 
close $ffh; 

你可能会更好细读奇尔卡特网站进一步不过,也有二进制数据示例代码。

+0

对我也有效,谢谢! – user30771

+2

请不要使用间接对象表示法('new chilkat :: CkByteData()')。我知道它在文档中,但这是一个迹象,表明作者对Perl不了解。间接对象​​表示法在某些情况下容易被误解,并且在追踪问题时会造成很多挫折。更好地使用替代语法 - 'chilkat :: CkByteData-> new()'。 –

+1

@DaveCross - 已更新。 –

0

我要写一个链接到一个比这里发布的示例好得多的示例。这里发布的例子并不完全正确。有两个重要的Chilkat Crypt2属性需要注意:FirstChunkLastChunk。默认情况下,这两个属性都是true(或Perl中的值1)。这意味着对于给定的加密/解密调用,例如EncryptBytes,DecryptBytes等,它假定已经传递了全部数据量。对于CBC模式,这很重要,因为IV用于第一个块,而对于最后一个块,输出会根据PaddingScheme属性的值填充到算法的块大小。

人们可以代替通过执行以下操作将输入数据馈送到加密块逐块:

  1. 对于第一组块,设置FirstChunk = 1,LastChunk = 0。
  2. 对于中间块,​​设置FirstChunk = 0,LastChunk = 0。
  3. 对于最后的块(即使是0字节的最终块),设置FirstChunk = 0,LastChunk = 1。这会导致最终填充的输出块被发射。

当使用FirstChunk/LastChunk传递块时,不需要担心传递的块匹配算法的块大小。如果一个部分块被传入,或者如果字节不是块大小的确切倍数(AES为16个字节),那么奇尔卡特将缓冲输入,并且部分块将被添加到在下一个块中传递的数据中。例如:

  1. FirstChunk = 1,LastChunk = 0,传入23个字节,输出为16个字节,缓冲7个字节。
  2. FirstChunk = 0,LastChunk = 0,在传递23个字节,输出是16个字节,(46-32字节)缓冲
  3. FirstChunk = 0的14个字节,LastChunk = 1,在通过5个字节,输出为32个字节,(14个缓冲的字节+5个以上= 19个字节,19个字节是一个完整的块(16个字节)加上3个字节的余数,填充为16,因此输出是32个字节,并且CBC流结束。