apoc v1.0.0-rc1 Apoc.Hazmat.AEAD.AESGCM View Source

Implementation of the AES block encryption standard as per FIPS PUB 197.

The functions in this module operate in GCM (Galois/Counter Mode) to provide fast Authenticated Encryption. See Recommendation for Block Cipher Modes of Operation: Galois/Counter Mode (GCM) and GMAC.

Additionally, three block sizes are support (128, 192 and 256). For those particularly paranoid users, a block size of 256 is recommended for defense against Shore's algorithm. Use a 32 byte key for a 256 bit block size. See encrypt/2.

Link to this section Summary

Functions

Decrypt a cipher text that has been encrypted under the given key.

Encrypt a message using AES under the given key

Link to this section Types

Specs

aes_key() :: <<_::16, _::_*8>> | <<_::24, _::_*8>> | <<_::32, _::_*8>>

Link to this section Functions

Specs

decrypt(String.t(), aes_key()) :: {:ok, binary()} | {:error, String.t()}

Decrypt a cipher text that has been encrypted under the given key.

Example

{:ok, plaintext} = Apoc.AES.decrypt(ciphertext, key)

Specs

encrypt(String.t(), aes_key()) :: {:ok, binary()} | {:error, binary()}

Encrypt a message using AES under the given key

The key should be a 16, 24 or 32 byte binary string

Example

Apoc.AES.encrypt("a secret message", Apoc.rand_bytes(16))

It's important that the key be as uniformly random as possible. Consequently, avoid the temptation to do this:

# Don't do this
k = Apoc.rand_bytes(16) |> Base.encode16
byte_size(k) # => 32
Apoc.AES.encrypt(message, k)

As the bytesize of the encoded key in this example is 32 bytes the 256 bit block size will be used. However, this is not a uniformly random key in {0,1}^32. Specifically, the probability of a key containing a character other than [0-9a-f] is zero.

To avoid this issue, don't use ASCII (e.g. hex of base 64 encoded strings) as the key. By all means, encode the key for storage purposes but make sure your key has been generated with the correct number of bytes.

k = Apoc.rand_bytes(32)
Apoc.AES.encrypt(message, k)

Apoc.encode(k) # => base 64 encoded for storage somewhere safe