The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Crypt::EAMessage - Simple-to-use Abstraction of Encrypted Authenticated Messages

VERSION

version 1.232011

SYNOPSIS

  use Crypt::EAMessage;

  my $eamsg = Crypt::EAMessage->new( hex_key => $hex );

  $encrypted    = $eamsg->encrypt_auth($input);
  $enc_ascii    = $eamsg->encrypt_auth_ascii($input);
  $enc_url      = $eamsg->encrypt_auth_urlsafe($input);
  $enc_portable = $eamsg->encrypt_auth_portable($input); # Input must be text

  $decrypted = $eamsg->decrypt_auth($encrypted);

DESCRIPTION

This module provides an easy-to-use method to create encrypted and authenticated messages from arbitrary Perl objects (anything compatible with Storable). Note that Perl 5.38+ Corinna class objects are not serializable with Storable.

While there are many modules that encrypt text, there are many less that provide encryption and authentication without a complex interface. This module uses AES encryption in CCM mode. This allows two parties to communicate securely, provided they both use the same secret key. In addition to providing privacy, this module also ensures that the message was created by someone who had knowledge of the private key - in otherwords the message was also not tampered with in-transit.

When encrypting, this module produces a message that contains the message's nonce (a unique value that changes the results of the encryption so two identical messages will be encrypted differently), the authentication tag (used to authenticate the message), and the cipher text. It can be formatted in either a "printable" base 64 encoding or in raw binary form.

ATTRIBUTES

raw_key

This is the key used for encryption/decryption (a string of 16, 24, or 32 bytes). Note that the size of the key determines the strength of the AES encryption - a 16 byte string uses AES-128, 24 uses AES-192, 32 uses AES-256.

hex_key

This is the hex version of the key. This should consist of a string of 32, 48, or 64 hex digits (creating a 16, 24, or 32 byte key).

METHODS

new

  my $eamsg = Crypt::EAMessage->new( raw_key => $key );

or

  my $eamsg = Crypt::EAMessage->new( hex_key => $hex );

Create a new workunit class. It takes either a raw_key or a hex_key parameter. See the raw_key and hex_key attributes.

encrypt_auth

  my $ciphertext = $ea->encrypt_auth( $plaintext );

Encrypts the plain text (or any other Perl object that Storable can freeze and thaw) passed as a parameter, generating a binary (non-printable) cipher text output.

encrypt_auth_ascii

  my $ciphertext = $ea->encrypt_auth_ascii( $plaintext );
  my $ciphertext = $ea->encrypt_auth_ascii( $plaintext, "" );

Encrypts the plain text (or any other Perl object that Storable can freeze and thaw) passed as a parameter, generating an ASCII (base64) cipher text output.

Starting in version 1.004, a second, optional, argument is allowed. If an argument after $plaintext is supplied, that becomes the line ending for the output text. If no argument is provided, a standard newline appropriate to the platform is used. Otherwise, the value of that string is used as the line ending, in the same way as it would be if passed as the MIME::Base64::encode_base64 function's second argument.

Note that when using line endings other than a blank ending (no line ending) or a standard newline, you should strip the new line identifier from the cypertext before calling the decrypt_auth_ascii method.

encrypt_auth_urlsafe

  my $ciphertext = $ea->encrypt_auth_urlsafe( $plaintext );

Added in version 1.006.

Encrypts the plain text (or any other Perl object that Storable can freeze and thaw) passed as a parameter, generating an ASCII (modified base64) cipher text output. This output is safe to pass as part of a query string or URL. Namely, it doesn't use the standard Base 64 characters + or /, replacing them with - and _ respectively. In addition, the cyphertext output will start with a "3" rather than the "2" that the base 64 variant starts with.

encrypt_auth_portable

  my $ciphertext = $ea->encrypt_auth_portable( $plaintext );

Added in version 1.190900

Encrypts the plain text (or byte string) passed as a parameter, generating an ASCII (modified base64) cipher text output. This output is safe to pass as part of a query string or URL. Namely, it doesn't use the standard Base 64 characters + or /, replacing them with - and _ respectively. In addition, the cyphertext output will start with a "4".

This is intended for cross-language compatibility, so it does not utilize store/thaw.

SECURITY NOTE: The contents of a zero length string can be determined from the length of the encrypted portable message.

decrypt_auth

  my $plaintext = $ea->decrypt_auth( $ciphertext );

Decrypts the cipher text into the object that was frozen during encryption.

If the authentication or decryption fails, an exception is thrown. Otherwise it returns the plaintext/object.

generate_key

 say "Hex key: " . Crypt::EAMessage->generate_key()

Added in version 1.220390

This is a class method (I.E. you do not need to instantiate the Crypt::EAMessage class to use this).

Returns a randomly generated key suitable to use with AES256 as a hex number.

GENERATING AES256 KEYS

To generate a key, a simple Perl program can accomplish this - note that you should NOT use standard rand() to do this.

  use feature 'say';
  use Crypt::EAMessage;

  my $hexkey = Crypt::EAMessage->generate_key()
  say "Key is: $hexkey";

Alternative, you can do this with a one-liner to return a hex key, and the Crypt::EAMessage::Keygen module:

  perl -MCrypt::EAMessage::Keygen -e 1

This will output a random key in hex format suitable for use as an AES256 key.

SECURITY

Note that this module use Storable. Thus this module should only be used when the endpoint is trusted. This module will ensure that the stored object is received without tampering by an intermediary (and is secure even when an untrusted third party can modify the encrypted message in transit), because thaw is not called unless the message passes authentication checks. But if an endpoint can create a malicious message using a valid key, it is possible that this message could exploit some vulnerability in the Storable module.

This module does not protect against replay attacks.

This module is not protected against timing attacks.

ALTERNATIVES

This module implements a tiny subset of the functionality in Crypt::Util which may be a better choice for more complex use cases.

BUGS

None known, however it is certainly possible that I am less than perfect! If you find any bug you believe has security implications, I would greatly appreciate being notified via email sent to jmaslak@antelope.net prior to public disclosure. In the event of such notification, I will attempt to work with you to develop a plan for fixing the bug.

All other bugs can be reported via email to jmaslak@antelope.net or by using the Git Hub issue tracker at https://github.com/jmaslak/Crypt-EAMessage/issues

AUTHOR

Joelle Maslak <jmaslak@antelope.net>

COPYRIGHT AND LICENSE

This software is copyright (c) 2019-2022 by Joelle Maslak.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.