DEV Community

Scotticles
Scotticles

Posted on • Edited on

1 1

Perl is dead simple with CBC Block Encryption

INTRO

I hope this blog post will help someone with CryptX.

My disclaimer: I am not an expert in cryptography.

I first started using Crypt::CBC but I liked how CryptX had more modules, better maintained and it was faster. I moved my system over to CryptX. In Crypt, the CBC piece was done more for you, where Crypt::Mode::CBC requires a little more from the developer to configure it.

WHY?

I am designing a system and needed a way to take files uploaded by users and encrypt them before storing them until needed. S3 has it built it, I know but I didn't want to rely on that. I decided to use CBC block as my encryption method. I also had to encrypt text and store them in the database, I can use the same encryption methods for both tasks. If you plan on storing in a database, remember these are bytes and needs to be a blob type.

HOW?

Here is the Crypt::Mode::CBC snippet

use Crypt::Mode::CBC;
my $m = Crypt::Mode::CBC->new('AES');

#(en|de)crypt at once
my $ciphertext = $m->encrypt($plaintext, $key, $iv);
Enter fullscreen mode Exit fullscreen mode

Crypt::Mode::CBC

It uses AES, requires a $key and a $iv. AES is one of the many Ciphers to use. The padding by default is PKCS5 padding.

vulnerabilities-cbc-mode - Extra Reading

What the heck is the IV?

The IV is 'initialization vector'. To make each message unique, an initialization vector must be used in the first block. IV Resource

I generate a IV for each encrypted object and store it in the database for when decryption is needed.
IV Resource

Here is a full example.
I use Mojo::File for file manipulation, it makes things easy.

Just to note, rand() is not cryptographically secure. Please see the doc for picking the right module, if you need a secure implementation. In this example I am using Math::Random::Secure that replaced the native rand()
https://perldoc.perl.org/functions/rand

Requires Modules:

  • Crypt::Mode::CBC
  • Mojo::File
  • Modern::Perl
  • Crypt::Digest::SHA512_256
  • Math::Random::Secure
use Crypt::Mode::CBC;
use Mojo::File;
use Modern::Perl;
use warnings;
use strict;
use Crypt::Digest::SHA512_256 qw( sha512_256_hex );
use Math::Random::Secure qw(rand);
my $key =  sha512_256_hex(rand(1000));
my $iv =  sha512_256_hex(rand(1000));

# Lets print out the IV and KEY for fun.
say $key;
say substr($iv, 0, 32);

my $cbc = Crypt::Mode::CBC->new('AES');

# Encrypt
my $file = Mojo::File->new('plainfile.txt');

my $ciphertext = $cbc->encrypt($file->slurp, pack("H*", $key), pack("H*", substr($iv, 0, 32)));

my $encFile = Mojo::File->new('plainfile.txt.crypted');
$encFile->spurt($ciphertext);

# Move the old file
$file->move_to('plainfile.txt.backup');
$file->new('plainfile.txt');

# Decrypt

my $plaintext = $cbc->decrypt($encFile->slurp, pack("H*", $key), pack("H*", substr($iv, 0, 32)));

$file->spurt($plaintext);
# this should print out the data and if you cat the file plainfile.txt, it should print out the data.
say $plaintext;
Enter fullscreen mode Exit fullscreen mode

If you run this, you will have a few files to look at.

AWS Security LIVE!

Join us for AWS Security LIVE!

Discover the future of cloud security. Tune in live for trends, tips, and solutions from AWS and AWS Partners.

Learn More

Top comments (2)

Collapse
 
thibaultduponchelle profile image
Tib • Edited

Great article ! Thank you 👍

I think you can highlight syntax by adding « perl » to your « quote quote quote »

Collapse
 
scotticles profile image
Scotticles

Thanks :D, added the perl syntax, was trying to figure that out but gave up. Looks way better.

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs