Cryptography libraries often have complicated APIs with many different options
to tweak. It is a goal PyCA's
cryptography library to provide safe and easy
to use APIs for common cryptographic tasks. To that end, the
package has a
Fernet recipe for symmetric encryption derived from the
original Ruby implementation and specification. However, the
Fernet recipe lacks the ability to authentiate (without encrypting) arbitrary
To make up for that use case not being covered by Fernet, I have written and
released on PyPI a library called
aead. It can be installed with
$ pip install aead
aead library is based on a IETF Internet Draft from David
McGrew. It is essentially
HMAC_SHA_256 composed with an
encrypt-then-mac construction. It relies on the
cryptography library for
the cryptographic primitives.
It has a simple to use API heavily inspired by the Fernet recipe in the
The module contains a single class that can be imported.
from aead import AEAD
The class takes requires an encryption key to be initialized. The key has to be
32 bytes long and encoded with base64url as specified in [[RFC4648]]. The
library provides a
classmethod to generate a suitable random key.
cryptor = AEAD(AEAD.generate_key())
After initializing the object, encryption can be done by calling the
.encrypt() method. The
.encrypt() method takes two paremeters, the first
being the data you want to encrypt and the second being associated data that
you want to authenticate but not encrypt. The second parameter is optional and
can be left out if there isn't any data to authenticate.
ct = cryptor.encrypt(b"Hello, World!", b"Additional Data")
.encrypt() returns base64url encoded cipher text.
Decrypting any data encrypted with
aead is similar. Simply call
in place of
.decrypt() method takes two parameters, the
first being the cipher text that needs decrypting and the second being the
associated data that was authenticated.
If the cipher text is corrupted or the associated data provided during the
decryption process does not match the associated data provided during
ValueError is raised, otherwise the decrypted plain text is
The repository for
aead can be found on GitHub and the
README.md file in the repository should be treated as the source of truth
if any information there differs from this blog post due to changes over time.