Search code examples
perlencryptionbase64rijndael

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;

Solution

  • 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