Search code examples
perlencryptionchilkat

Chilkat encryption doesn't work as expected


I was trying to test file encryption using the chilkat functionality. Based on code found on this example page, I replaced the last part with 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;

Disclaimer: I know the CBC mode is not recommended for file encryption because if one block is lost, the other blocks are lost too. The output file is corrupted and when I look with beyond compare at the two files, there are chunks of the file which match and there are chunks of file which doesn't. What am I doing wrong?


Solution

  • You're trying to use character string encryption (encryptStringENC(), decryptStringENC()) for what is, at least partly, a binary file.

    This worked for me:

    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;
    

    You likely better off perusing the Chilkat site further though, there are sample codes for binary data.