NAME
    Crypt::OpenSSL::AES - A Perl wrapper around OpenSSL's AES library

SYNOPSIS
         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 implements 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).

    This module is compatible with Crypt::CBC (and likely other modules that
    utilize a block cipher to make a stream cipher).

    This module is 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.

    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.

        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).

        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.

    AES-ECB is not approved for general data encryption under FIPS 140-3.
    Use AES-CBC or AES-CTR with a random IV instead.

        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.

    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().

    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.

            # 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.

        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.

    $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.

        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.

    $cipher->fips_mode()
        Will return true (1) or false (0) depending whether the openssl
        'fips=yes' default property is set.

    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.

    blocksize
        This method is used by Crypt::CBC to check the block size. The
        blocksize for AES is always 16 bytes.

  USE WITH CRYPT::CBC
    As padding is now supported for the CBC cipher, Crypt::CBC is no longer
    required but supported for backward compatibility.

            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
    Crypt::CBC

    http://www.openssl.org/

    http://en.wikipedia.org/wiki/Advanced_Encryption_Standard

    http://www.csrc.nist.gov/encryption/aes/

BUGS
    Need more (and better) test cases.

AUTHOR
    Tolga Tarhan, <cpan at ttar dot org>

    The US Government's Advanced Encryption Standard is the Rijndael
    Algorithm and was developed by Vincent Rijmen and Joan Daemen.

COPYRIGHT AND LICENSE
    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.

