Kryptonite v0.1.11 Kryptonite.AES View Source

This module allows to easily perform AES related operations, such as generating keys, encrypting and decripting.

Examples

A successful flow of key / iv generation, encryption and decryption can be illustrated such as:

iex> {key, iv} = {generate_key!(), Random.bytes!(16)}
iex> {:ok, cypher} = encrypt_cbc(key, iv, "Message...")
iex> decrypt_cbc(key, iv, cypher)
"Message..."

In GCM mode, the same flow could be performed like so:

iex> {key, iv} = {generate_key!(), Random.bytes!(16)}
iex> ad = "Authentication data used to guard decryption."
iex> {:ok, cypher, tag} = encrypt_gcm(key, iv, ad, "Message...")
iex> decrypt_gcm(key, iv, ad, cypher, tag)
{:ok, "Message..."}

The advantage of GCM Mode is that it lets you know when the message cannot be decrypted properly. In other modes, you just end up with a decrypted garbaged message.

iex> {key, wrong_key, iv} = {generate_key!(), generate_key!(), Random.bytes!(16)}
iex> ad = "Authentication data used to guard decryption."
iex> {:ok, cypher, tag} = encrypt_gcm(key, iv, ad, "Message...")
iex> decrypt_gcm(wrong_key, iv, ad, cypher, tag)
{:error, :decryption_error}

Link to this section Summary

Types

A cypher is a binary of any shape

Initialization vectors must be at least 128 bits

A key is a 256 bit length bitstring

A padded binary can only be multiple of 128 bits long

A cypher tag is a binary of any shape

Functions

Decrypts a cypher using AES in CBC mode

Decrypts a cypher using AES in GCM mode

Derives an AES key deterministically based on a password

Encrypt a msg with AES in CBC mode

Encrypt a msg with AES in GCM mode

Generates an AES key

Generates an AES key

Check integrity then decrypts a stream encrypted with stream_encrypt/5

Decrypts a stream using AES in CTR mode

Encrypts a stream using AES in CTR mode

Encrypts + HMAC a stream into a Collectable

Returns computed AES + HMAC encoded stream tag

Link to this section Types

A cypher is a binary of any shape.

Link to this type iv() View Source
iv() :: <<_::128, _::_*8>>

Initialization vectors must be at least 128 bits.

Link to this type key() View Source
key() :: <<_::256>>

A key is a 256 bit length bitstring.

Link to this type padded() View Source
padded() :: <<_::_*128>>

A padded binary can only be multiple of 128 bits long.

A cypher tag is a binary of any shape.

Link to this section Functions

Link to this function decrypt_cbc(key, iv, cypher) View Source
decrypt_cbc(key(), iv(), cypher()) :: binary()

Decrypts a cypher using AES in CBC mode.

This function must be provided with the same initialization vector iv that was used to perform the encryption.

Examples

iex> {key, iv} = {generate_key!(), Random.bytes!(16)}
iex> msg = "Message..."
iex> {:ok, cypher} = encrypt_cbc(key, iv, msg)
iex> msg == decrypt_cbc(key, iv, cypher)
true
Link to this function decrypt_gcm(key, iv, ad, cypher, tag) View Source
decrypt_gcm(key(), iv(), binary(), cypher(), tag()) ::
  {:ok, binary()} | {:error, any()}

Decrypts a cypher using AES in GCM mode.

Examples

iex> {key, iv} = {generate_key!(), Random.bytes!(16)}
iex> ad = "Auth data..."
iex> {:ok, cypher, tag} = encrypt_gcm(key, iv, ad, "Message...")
iex> decrypt_gcm(key, iv, ad, cypher, tag)
{:ok, "Message..."}
Link to this function derive_key(password, opts) View Source
derive_key(String.t(), keyword()) :: key()

Derives an AES key deterministically based on a password.

Link to this function encrypt_cbc(key, iv, msg) View Source
encrypt_cbc(key(), iv(), binary()) :: {:ok, cypher()} | {:error, any()}

Encrypt a msg with AES in CBC mode.

Returns a tuple containing the initialization_vector, and cypher. At a high level encryption using AES in CBC mode looks like this:

key + msg -> iv + cypher

Examples

iex> {:ok, cypher} = encrypt_cbc(generate_key!(), Random.bytes!(16), "Message...")
iex> is_bitstring(cypher)
true
Link to this function encrypt_gcm(key, iv, ad, msg) View Source
encrypt_gcm(key(), iv(), binary(), binary()) ::
  {:ok, cypher(), tag()} | {:error, any()}

Encrypt a msg with AES in GCM mode.

Returns a tuple containing the initialization_vector, and cypher. At a high level encryption using AES in GCM mode looks like this:

key + iv + ad + msg -> cypher + tag

Examples

iex> {key, iv} = {generate_key!(), Random.bytes!(16)}
iex> {:ok, cypher, tag} = encrypt_gcm(key, iv, "Auth", "Message...")
iex> is_binary(cypher) and is_binary(tag)
true
Link to this function generate_key!() View Source
generate_key!() :: key() | {:error, any()}

Generates an AES key.

Link to this function generate_key() View Source
generate_key() :: {:ok, key()} | {:error, any()}

Generates an AES key.

Link to this function stream_decrypt!(in_stream, key, iv, ad, tag) View Source
stream_decrypt!(Enumerable.t(), key(), binary(), iv(), tag()) ::
  Enumerable.t()

Check integrity then decrypts a stream encrypted with stream_encrypt/5

Raise Kryptonite.AES.StreamIntegrityError in case of integrity checking error.

Examples

iex> {key, iv} = {generate_key!(), Random.bytes!(16)}
iex> fid = 1000000 |> :rand.uniform() |> to_string
iex> {plain, enc} = {"/tmp/#{fid}.txt", "/tmp/#{fid}.aes"}
iex> File.write!(plain, "This is a secret")
iex> {:ok, tag} = plain
...>   |> File.stream!()
...>   |> stream_encrypt(File.stream!(enc), key, iv, "Auth...")
iex> enc
...>   |> File.stream!()
...>   |> stream_decrypt!(key, iv, "Auth...", tag)
...>   |> Enum.to_list()
...>   |> IO.iodata_to_binary()
"This is a secret"
Link to this function stream_decrypt(stream, key, iv) View Source
stream_decrypt(Enumerable.t(), key(), iv()) :: Enumerable.t()

Decrypts a stream using AES in CTR mode.

Examples

iex> {key, iv} = {generate_key!(), Random.bytes!(16)}
iex> "This is a secret..."
...>   |> String.to_charlist()
...>   |> stream_encrypt(key, iv)
...>   |> Enum.to_list()
...>   |> stream_decrypt(key, iv)
...>   |> Enum.to_list()
...>   |> :erlang.iolist_to_binary
"This is a secret..."
Link to this function stream_encrypt(stream, key, iv) View Source
stream_encrypt(Enumerable.t(), key(), iv()) :: Enumerable.t()

Encrypts a stream using AES in CTR mode.

Examples

iex> {key, iv} = {generate_key!(), Random.bytes!(16)}
iex> 'This is a secret'
...>   |> stream_encrypt(key, iv)
...>   |> Enum.to_list()
...>   |> is_list()
true
Link to this function stream_encrypt(in_stream, out_stream, key, iv, ad) View Source
stream_encrypt(Enumerable.t(), Collectable.t(), key(), iv(), binary()) ::
  {:ok, tag()}

Encrypts + HMAC a stream into a Collectable

Examples

iex> {key, iv} = {generate_key!(), Random.bytes!(16)}
iex> fid = 1000000 |> :rand.uniform() |> to_string
iex> {plain, enc} = {"/tmp/#{fid}.txt", "/tmp/#{fid}.aes"}
iex> File.write!(plain, "This is a secret")
iex> {:ok, tag} = plain
...>   |> File.stream!()
...>   |> stream_encrypt(File.stream!(enc), key, iv, "Auth...")
iex> Enum.each([plain, enc], &File.rm!/1)
iex> is_binary(tag)
true
Link to this function stream_tag(stream, key) View Source
stream_tag(Enumerable.t(), binary()) :: tag()

Returns computed AES + HMAC encoded stream tag