ASG ASG - 5 months ago 21
Perl Question

Rijndael CBC encryption decryption in Perl

I have perl code for encrypting/decrypting below. The encryption seams to be working. The decryption isn't restoring the original. Original: 4111111111111111 Encrypted: IW7K95q8p1Wa89CQ2DoIxQ== Decrypted: §À@ŽŒ¦õúbp
I need the decrytion to match the original. Any ideas? Any additional suggestions?

use strict;
use warnings;
use feature qw( say );

use Crypt::CBC qw( );
use MIME::Base64 qw( encode_base64 decode_base64 );

sub decrypt {
my $my_string=@_;
my $cipher = Crypt::CBC->new(
{
'key' => 'length16length16',
'cipher' => 'Rijndael',
'iv' => '1234567890abcdef',
'literal_key' => 1,
'padding' => 'null',
'header' => 'none',
keysize => 128 / 8
}
);
my $return = $cipher->decrypt($my_string);
return $return;
}

sub encrypt {
my $my_string=@_;
my $cipher = Crypt::CBC->new(
{
'key' => 'length16length16',
'cipher' => 'Rijndael',
'iv' => '1234567890abcdef',
'literal_key' => 1,
'padding' => 'null',
'header' => 'none',
keysize => 128 / 8
}
);
my $return = encode_base64($cipher->encrypt($my_string));
return $return;
}

my $cc = '4111111111111111';
my $coded = encrypt($cc);
say $coded;
my $decoded = decrypt($coded);
say $decoded;

Answer

Error 1

The following assigns the number of elements in @_ (1) to $mystring:

my $my_string=@_;

You want:

my ($my_string) = @_;

Error 2

You encoded the data using base64 during encryption, but you don't have a corresponding decode_base64 during decryption.

Error 3

WHAT YOU HAVE IS VERY INSECURE!

You're defying a number of security mechanisms by using literal_key with a text password and by using a constant iv.

Note that padding with null only works if the plaintext can't contain NUL characters. It's not a very appropriate padding method.

I don't know what are the implications of using a 16-byte key instead of the default 32-byte key.

Error 4

encode_base64 is being misused, since you don't want a newlines in the encoded string. Replace encode_base64($s) with encode_base64($s, '').

Error 5

Your indenting sucks.

Solution

#!/usr/bin/perl    
use strict;
use warnings;
use feature qw( say );

use Crypt::CBC   qw( );
use MIME::Base64 qw( encode_base64 decode_base64 );

my $key = 'length16length16';

my $cipher = Crypt::CBC->new({
    cipher => 'Rijndael',
    key    => $key,
});

sub decrypt {
    my ($my_string) = @_;
    return $cipher->decrypt(decode_base64($my_string));
}

sub encrypt {
    my ($my_string) = @_;
    return encode_base64($cipher->encrypt($my_string), '');
}

{
    my $cc = '4111111111111111';
    my $coded = encrypt($cc);
    say $coded;
    my $decoded = decrypt($coded);
    say $decoded;
}

Output:

U2FsdGVkX1/QYQrNSEadlko4jtKdjM+yNaW0ZnCAmhyHHz0NyDL+id6BsM2kVPGw
4111111111111111