ExCrypto (ExCrypto v0.10.0)
The ExCrypto module exposes a subset of functionality from the Erlang crypto
module with the goal of making it easier to include strong cryptography in your
Elixir applications.
This module provides functions for symmetric-key cryptographic operations using AES in GCM and CBC mode. The ExCrypto module attempts to reduce complexity by providing some sane default values for common operations.
Link to this section Summary
Functions
Split and decode the three parts of an encrypted payload and encode using Base.url_decode64
.
Returns a clear-text string decrypted with AES256 in CBC mode.
Returns a clear-text string decrypted with AES in GCM mode.
Join the three parts of an encrypted payload and encode using Base.url_encode64
.
Encrypt a binary
with AES in CBC mode.
Same as encrypt/4
except the initialization_vector
is automatically generated.
Encrypt a binary
with AES in GCM mode.
Returns an AES key.
Returns a string of random where the length is equal to integer
.
Returns random characters. Each character represents 6 bits of entropy.
Returns a random integer between low
and high
.
Link to this section Functions
decode_payload(encoded_parts)
Specs
Split and decode the three parts of an encrypted payload and encode using Base.url_decode64
.
Examples
iex> clear_text = "my-clear-text"
iex> auth_data = "my-auth-data"
iex> {:ok, aes_256_key} = ExCrypto.generate_aes_key(:aes_256, :bytes)
iex> {:ok, {_ad, {init_vec, cipher_text, cipher_tag}}} = ExCrypto.encrypt(aes_256_key, auth_data, clear_text)
iex> {:ok, encoded_payload} = ExCrypto.encode_payload(init_vec, cipher_text, cipher_tag)
iex> assert(String.valid?(encoded_payload))
true
iex> {:ok, {d_init_vec, d_cipher_text, d_cipher_tag}} = ExCrypto.decode_payload(encoded_payload)
iex> assert(d_init_vec == init_vec)
true
iex> assert(d_cipher_text == cipher_text)
true
iex> assert(d_cipher_tag == cipher_tag)
true
decrypt(key, initialization_vector, cipher_text)
Specs
decrypt(binary(), binary(), binary()) :: {:ok, binary()} | {:error, :decrypt_failed} | {:error, binary()}
Returns a clear-text string decrypted with AES256 in CBC mode.
At a high level decryption using AES in CBC mode looks like this:
key + init_vec + cipher_text -> clear_text
Examples
iex> clear_text = "my-clear-text"
iex> {:ok, aes_256_key} = ExCrypto.generate_aes_key(:aes_256, :bytes)
iex> {:ok, {init_vec, cipher_text}} = ExCrypto.encrypt(aes_256_key, clear_text)
iex> {:ok, val} = ExCrypto.decrypt(aes_256_key, init_vec, cipher_text)
iex> assert(val == clear_text)
true
decrypt(key, authentication_data, initialization_vector, cipher_text, cipher_tag)
Specs
decrypt(binary(), binary(), binary(), binary(), binary()) :: {:ok, binary()} | {:error, :decrypt_failed} | {:error, binary()}
Returns a clear-text string decrypted with AES in GCM mode.
At a high level decryption using AES in GCM mode looks like this:
key + init_vec + auth_data + cipher_text + cipher_tag -> clear_text
Examples
iex> clear_text = "my-clear-text"
iex> auth_data = "my-auth-data"
iex> {:ok, aes_256_key} = ExCrypto.generate_aes_key(:aes_256, :bytes)
iex> {:ok, {_ad, payload}} = ExCrypto.encrypt(aes_256_key, auth_data, clear_text)
iex> {init_vec, cipher_text, cipher_tag} = payload
iex> {:ok, val} = ExCrypto.decrypt(aes_256_key, auth_data, init_vec, cipher_text, cipher_tag)
iex> assert(val == clear_text)
true
encode_payload(initialization_vector, cipher_text, cipher_tag)
Specs
Join the three parts of an encrypted payload and encode using Base.url_encode64
.
This produces a Unicode payload
string like this:
init_vec <> cipher_text <> cipher_tag
[128 bits] <> [?? bits] <> [128 bits]
This format is convenient to include in HTTP request bodies. It can also be used with JSON transport formats.
Examples
iex> clear_text = "my-clear-text"
iex> auth_data = "my-auth-data"
iex> {:ok, aes_256_key} = ExCrypto.generate_aes_key(:aes_256, :bytes)
iex> {:ok, {_ad, {init_vec, cipher_text, cipher_tag}}} = ExCrypto.encrypt(aes_256_key, auth_data, clear_text)
iex> {:ok, encoded_payload} = ExCrypto.encode_payload(init_vec, cipher_text, cipher_tag)
iex> assert(String.valid?(encoded_payload))
true
encrypt(key, clear_text)
Specs
Encrypt a binary
with AES in CBC mode.
Returns a tuple containing the initialization_vector
, and cipher_text
.
At a high level encryption using AES in CBC mode looks like this:
key + clear_text -> init_vec + cipher_text
Examples
iex> clear_text = "my-clear-text"
iex> {:ok, aes_256_key} = ExCrypto.generate_aes_key(:aes_256, :bytes)
iex> {:ok, {_iv, cipher_text}} = ExCrypto.encrypt(aes_256_key, clear_text)
iex> assert(is_bitstring(cipher_text))
true
encrypt(key, clear_text, clear_text)
Specs
encrypt(binary(), binary(), %{initialization_vector: binary()}) :: {:ok, {binary(), {binary(), binary(), binary()}}} | {:ok, {binary(), binary()}} | {:error, any()}
encrypt(binary(), binary(), binary()) :: {:ok, {binary(), {binary(), binary(), binary()}}} | {:error, binary()}
Same as encrypt/4
except the initialization_vector
is automatically generated.
A 128 bit initialization_vector
is generated automatically by encrypt/3
. It returns a tuple
containing the initialization_vector
, the cipher_text
and the cipher_tag
.
Examples
iex> clear_text = "my-clear-text"
iex> auth_data = "my-auth-data"
iex> {:ok, aes_256_key} = ExCrypto.generate_aes_key(:aes_256, :bytes)
iex> {:ok, {_ad, payload}} = ExCrypto.encrypt(aes_256_key, auth_data, clear_text)
iex> {_init_vec, cipher_text, cipher_tag} = payload
iex> assert(is_bitstring(cipher_text))
true
iex> assert(bit_size(cipher_tag) == 128)
true
encrypt(key, authentication_data, initialization_vector, clear_text)
Specs
encrypt(binary(), binary(), binary(), binary()) :: {:ok, {binary(), {binary(), binary(), binary()}}} | {:error, binary()}
Encrypt a binary
with AES in GCM mode.
Returns a tuple containing the initialization_vector
, the cipher_text
and the cipher_tag
.
At a high level encryption using AES in GCM mode looks like this:
key + init_vec + auth_data + clear_text -> cipher_text + cipher_tag
Examples
iex> clear_text = "my-clear-text"
iex> auth_data = "my-auth-data"
iex> {:ok, aes_256_key} = ExCrypto.generate_aes_key(:aes_256, :bytes)
iex> {:ok, iv} = ExCrypto.rand_bytes(16)
iex> {:ok, {_ad, payload}} = ExCrypto.encrypt(aes_256_key, auth_data, iv, clear_text)
iex> {_iv, cipher_text, cipher_tag} = payload
iex> assert(is_bitstring(cipher_text))
true
iex> assert(bit_size(cipher_tag) == 128)
true
generate_aes_key(key_type, key_format)
Specs
Returns an AES key.
Accepts a key_type
(:aes_128
|:aes_192
|:aes_256
) and key_format
(:base64
|:bytes
) to determine type of key to produce.
Examples
iex> {:ok, key} = ExCrypto.generate_aes_key(:aes_256, :bytes)
iex> assert bit_size(key) == 256
true
iex> {:ok, key} = ExCrypto.generate_aes_key(:aes_256, :base64)
iex> assert String.length(key) == 44
true
iex> {:ok, key} = ExCrypto.generate_aes_key(:aes_192, :bytes)
iex> assert bit_size(key) == 192
true
iex> {:ok, key} = ExCrypto.generate_aes_key(:aes_192, :base64)
iex> assert String.length(key) == 32
true
iex> {:ok, key} = ExCrypto.generate_aes_key(:aes_128, :bytes)
iex> assert bit_size(key) == 128
true
iex> {:ok, key} = ExCrypto.generate_aes_key(:aes_128, :base64)
iex> assert String.length(key) == 24
true
pad(data, block_size)
rand_bytes(length)
Specs
Returns a string of random where the length is equal to integer
.
Examples
iex> {:ok, rand_bytes} = ExCrypto.rand_bytes(16)
iex> assert(byte_size(rand_bytes) == 16)
true
iex> assert(bit_size(rand_bytes) == 128)
true
iex> {:ok, rand_bytes} = ExCrypto.rand_bytes(24)
iex> assert(byte_size(rand_bytes) == 24)
true
iex> assert(bit_size(rand_bytes) == 192)
true
iex> {:ok, rand_bytes} = ExCrypto.rand_bytes(32)
iex> assert(byte_size(rand_bytes) == 32)
true
iex> assert(bit_size(rand_bytes) == 256)
true
rand_bytes!(length)
Specs
rand_chars(num_chars)
Specs
Returns random characters. Each character represents 6 bits of entropy.
Accepts an integer
to determine the number of random characters to return.
Examples
iex> rand_string = ExCrypto.rand_chars(24)
iex> assert(String.length(rand_string) == 24)
true
iex> rand_string = ExCrypto.rand_chars(32)
iex> assert(String.length(rand_string) == 32)
true
iex> rand_string = ExCrypto.rand_chars(44)
iex> assert(String.length(rand_string) == 44)
true
rand_int(low, high)
Specs
Returns a random integer between low
and high
.
Accepts two integer
arguments for the low
and high
boundaries. The low
argument
must be less than the high
argument.
Examples
iex> rand_int = ExCrypto.rand_int(2, 20)
iex> assert(rand_int > 1)
true
iex> assert(rand_int < 21)
true
iex> rand_int = ExCrypto.rand_int(23, 99)
iex> assert(rand_int > 22)
true
iex> assert(rand_int < 99)
true
iex> rand_int = ExCrypto.rand_int(212, 736)
iex> assert(rand_int > 211)
true
iex> assert(rand_int < 737)
true