ExCrypto v0.10.0 ExCrypto
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
rand_chars(num_chars)
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)
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