Crypt::...SSL::AES(3)

πŸ“¦
version 0.23 Β· 5 versions
, in epel 10

okay so welcome to the Crypt::...SSL::AES(3) page from the User Contributed Perl Documentation πŸ’… this is the whole tea on Crypt::OpenSSL::AES, a Perl wrapper around OpenSSL's AES library. buckle up bestie, we're getting into the cipher lore ✨

🌸 NAME 🌸

Crypt::OpenSSL::AES β€” a Perl wrapper around OpenSSL's AES library. that's the whole name, no cap πŸ’–

✨ SYNOPSIS ✨

okay so here's the starter pack. literally the synopsis, copied with love:

use Crypt::OpenSSL::AES;
use Crypt::URandom qw( urandom );  # Always use a strong random source

# Basic usage (defaults to AES-ECB based on key length; ECB is not recommended)
my $key    = urandom(32);
my $cipher = Crypt::OpenSSL::AES->new($key);

# Recommended usage: AES-256-CBC with proper Initialization Vector and Padding
my $secure_key = urandom(32); # 32 bytes (256 bits) for AES-256
my $iv         = urandom(16); # 16 bytes (128 bits) block size for AES

my $secure_cipher = Crypt::OpenSSL::AES->new(
    $secure_key,
    {
        cipher  => 'AES-256-CBC',
        iv      => $iv,
        padding => 1, # 1 for standard block padding, 0 for no padding
    }
);

my $plaintext = "Confidential data to be encrypted.";
my $encrypted = $secure_cipher->encrypt($plaintext);
my $decrypted = $secure_cipher->decrypt($encrypted);

πŸ’– DESCRIPTION πŸ’–

this module is a wrapper around OpenSSL. specifically, it wraps the methods related to the US Government's Advanced Encryption Standard (the Rijndael algorithm). the original version supports only AES ECB (electronic codebook mode encryption) β€” and yeah, ECB is not recommended, bestie, the synopsis even says so 😭

it's compatible with Crypt::CBC (and likely other modules that utilize a block cipher to make a stream cipher). it's an alternative to the implementation provided by Crypt::Rijndael, which implements AES itself. in contrast, this module is simply a wrapper around the OpenSSL library. iconic behavior πŸ’…

as of version 0.09 additional AES ciphers are supported. those are:

🧱 Block Ciphers

the blocksize is 16 bytes and must be padded if not a multiple of the blocksize. periodt.

  • AES-128-ECB, AES-192-ECB and AES-256-ECB (no IV) β€” supports padding
  • AES-128-CBC, AES-192-CBC and AES-256-CBC β€” supports padding and iv

🌊 Stream Ciphers

the blocksize is 1 byte. OpenSSL does not pad even if padding is set (the default). slay for stream mode, but know the rules 🫢

  • AES-128-CFB, AES-192-CFB and AES-256-CFB β€” supports iv
  • AES-128-CTR, AES-192-CTR and AES-256-CTR β€” supports iv
  • AES-128-OFB, AES-192-OFB and AES-256-OFB β€” supports iv

πŸ” FIPS COMPLIANCE πŸ”

when using OpenSSL 3.0+ built with FIPS support, pass provider_props => 'fips=yes' to the constructor to ensure only FIPS-validated algorithm implementations are used. no vibes-based crypto here, bestie βœ…

AES-ECB is not approved for general data encryption under FIPS 140-3. use AES-CBC or AES-CTR with a random IV instead. this is a hard caveat, okay? not a suggestion πŸ’€

my $cipher = Crypt::OpenSSL::AES->new($key, {
    cipher         => 'AES-256-CBC',
    iv             => $iv,
    padding        => 1,
    provider_props => 'fips=yes',
});

# Check at runtime:
warn "FIPS mode active\n" if Crypt::OpenSSL::AES::fips_mode();

🧡 mod_perl / THREADED ENVIRONMENTS 🧡

never store a Crypt::OpenSSL::AES object in a package variable under mod_perl with the worker or event MPM. each request handler must construct its own object. the underlying EVP_CIPHER_CTX is not thread-safe. this is the one where you listen, bestie 😭

under prefork MPM this restriction does not apply, but you should still avoid constructing cipher objects at use time (i.e., at server startup before the fork), because OpenSSL's PRNG state is not safely shared across fork(). lowkey important 🫢

recommended pattern for mod_perl handlers:

sub handler {
    my $r = shift;
    my $cipher = Crypt::OpenSSL::AES->new($key, { ... });
    # use $cipher only within this request
}

# httpd.conf or startup.pl
PerlChildInitHandler sub {
    Crypt::OpenSSL::AES::post_fork_init();
}

🌟 new()

for compatibility with old versions you can simply pass the key to the new constructor. yes, the old way still works, but read the labels pls:

# The default cipher is AES-ECB based on the key size
my $cipher = Crypt::OpenSSL::AES->new($key);

or

# the keysize must match the cipher size
# 16-bytes (128-bits) AES-128-xxx
# 24-bytes (192-bits) AES-192-xxx
# 32-bytes (256-bits) AES-256-xxx
my $cipher = Crypt::OpenSSL::AES->new($key,
                {
                    cipher  => 'AES-256-CBC',
                    iv      => $iv, # (16-bytes for supported ciphers)
                    padding => 1, (0 - no padding, 1 - padding)
                });

# cipher
#   AES-128-ECB, AES-192-ECB and AES-256-ECB (no IV)
#   AES-128-CBC, AES-192-CBC and AES-256-CBC
#   AES-128-CFB, AES-192-CFB and AES-256-CFB
#   AES-128-CTR, AES-192-CTR and AES-256-CTR
#   AES-128-OFB, AES-192-OFB and AES-256-OFB
#
# iv - 16-byte random data
#
# padding
#   0 - no padding
#   1 - padding

πŸ”’ $cipher->encrypt($data)

encrypt data. for Block Ciphers (ECB and CBC) the size of $data must be exactly blocksize in length (16 bytes) or padding must be enabled in the new constructor, otherwise this function will croak. croak means it's gonna throw hands, okay? 😀

for Stream ciphers (CFB, CTR or OFB) the block size is considered to be 1 byte and no padding is required.

Crypt::CBC is no longer required to encrypt/decrypt data of arbitrary lengths. we love an upgrade πŸ’–

πŸ”“ $cipher->decrypt($data)

decrypts data. for Block Ciphers (ECB and CBC) the size of $data must be exactly blocksize in length (16 bytes) or padding must be enabled in the new constructor, otherwise this function will croak. same energy as encrypt, bestie 😌

for Stream ciphers (CFB, CTR or OFB) the block size is considered to be 1 byte and no padding is required.

Crypt::CBC is no longer required to encrypt/decrypt data of arbitrary lengths. still iconic πŸ’…

πŸ•΅οΈ $cipher->fips_mode()

will return true (1) or false (0) depending whether the openssl 'fips=yes' default property is set. that's it, that's the method βœ…

πŸ“ keysize

this method is used by Crypt::CBC to verify the key length. this module actually supports key lengths of 16, 24, and 32 bytes, but this method always returns 32 for Crypt::CBC's sake. iconic compromise πŸ’…

🧱 blocksize

this method is used by Crypt::CBC to check the block size. the blocksize for AES is always 16 bytes. no cap.

🧸 USE WITH CRYPT::CBC

as padding is now supported for the CBC cipher, Crypt::CBC is no longer required but supported for backward compatibility. so if you're old-school, you're still invited to the party πŸŽ€

use Crypt::CBC;

my $plaintext = "This is a test!!";
my $password = "qwerty123";
my $cipher = Crypt::CBC->new(
        -key    => $password,
        -cipher => "Crypt::OpenSSL::AES",
        -pbkdf  => 'pbkdf2',
);

my $encrypted = $cipher->encrypt($plaintext);
my $decrypted = $cipher->decrypt($encrypted);

πŸ‘€ SEE ALSO πŸ‘€

πŸ› BUGS πŸ›

the bug list is literally: Need more (and better) test cases. that's the whole mood. if you got tests, contribute bestie 🫢

πŸ‘‘ AUTHOR πŸ‘‘

Tolga Tarhan, <cpan at ttar dot org>. king behavior πŸ‘‘

the US Government's Advanced Encryption Standard is the Rijndael Algorithm and was developed by Vincent Rijmen and Joan Daemen. credit where it's due πŸ’œ

Copyright (C) 2006 - 2024 DelTel, Inc. πŸ“…

this library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.5 or, at your option, any later version of Perl 5 you may have available. legal bestie realness, periodt βš–οΈ

mwah πŸ’‹ cute little sign-off: this manual glow-up ships with perl v5.40.2, dated 2026-04-07, and it's the Crypt::...SSL::AES(3) page. go encrypt responsibly, bestie 🫢✨

πŸ“¦ where this page comes from