Artur Szymczak
Artur Szymczak

Reputation: 135

Perl Crypt:CBC encrypts/decrypts only first list

Here is my code:

#!/usr/bin/perl -w
use Crypt::CBC;

my $scriptkey = qx(cat /tmp/scriptkeyfile);
chomp $scriptkey;

print new Crypt::CBC(-key=>"$scriptkey",-salt=>"my_salt")->encrypt(qx(cat $ARGV[0]));

This script only encrypts first line of given file. If I change encrypt to decrypt, it will only decrypt one line of given file. How to change this, to crypt whole file.

Upvotes: 2

Views: 432

Answers (2)

ikegami
ikegami

Reputation: 385915

qx is list context returns a list of lines, so

->encrypt(qx( ... ))

results in

->encrypt($line1, $line2, $line3, ...)

but

->encrypt($plaintext)

is expected. Use qx in scalar context to return the entire output as one scalar.

my $file = qx( prog ... );
die("Can't execute prog: $!\n") if $? == -1;
die("prog killed by signal ".( $? & 0x7F )."\n") if $? & 0x7F;
die("prog exited with error ".( $? >> 8 )."\n") if $? >> 8;

my $cypher = Crypt::CBC->new( ... );
print $cypher->encrypt($file);

I'm assuming you aren't actually using cat, that it's just an example.

Upvotes: 1

simbabque
simbabque

Reputation: 54333

The Crypt::CBC docs actually explain how to encrypt a whole file.

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.

In a typical application you will read the plaintext from a file or input stream and write the result to standard output in a loop that might look like this:

   $cipher = new Crypt::CBC('hey jude!');
   $cipher->start('encrypting');
   print $cipher->crypt($_) while <>;
   print $cipher->finish();

So your program might look like this.

use strict;
use warnings;
use Crypt::CBC;
use File::Slurp;

my $scriptkey = read_file( '/tmp/scriptkeyfile' );
chomp $scriptkey;

open my $fh, '<', $ARGV[0] or die $!; # sanitize this!!!

my $encrypted;
my $cipher = Crypt::CBC->new( -key => $scriptkey, -salt => "my_salt" );
$cipher->start('encrypting');
$encrypted .= $cipher->crypt($_) while <$fh>;
$encrypted .= $cipher->finish;

close $fh;

Upvotes: 1

Related Questions