Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mikalv/979932ac92493bc3ad3f2bb4595a7890 to your computer and use it in GitHub Desktop.
Save mikalv/979932ac92493bc3ad3f2bb4595a7890 to your computer and use it in GitHub Desktop.
Example usages of AES-GCM with libsodium
# Static Constants
plain_text = "test"
plain_text_size = byte_size(plain_text)
aad = "A256GCM" # AAD (Additional Authenticated Data)
####################################
# Example 1: Direct Key Encryption #
####################################
# In this example, the CEK must be known by the encryptor and decryptor (ie. a shared secret)
ex1_cek = "abcdefghijklmnopqrstuvwxyz012345" # 256-bit CEK (Content Encryption Key)
# The IV is randomly generated.
ex1_iv = :crypto.strong_rand_bytes(12) # 96-bit IV (Initialization Vector)
# <<25,1,99,98,143,27,98,129,74,88,227,112>>
# The Tag will be 128-bits when using AES-GCM.
<<
ex1_cipher_text::binary-size(plain_text_size),
ex1_cipher_tag::bitstring-size(128)
>> = :libsodium_crypto_aead_aes256gcm.encrypt(plain_text, aad, ex1_iv, ex1_cek)
# The following is intended to be publicly visible.
ex1_public = {aad, ex1_iv, ex1_cipher_text, ex1_cipher_tag}
# {"A256GCM", <<25,1,99,98,143,27,98,129,74,88,227,112>>, <<229,177,117,71>>, <<17,225,28,12,138,229,59,184,232,210,25,61,103,151,141,20>>}
# And the decryption of the content:
ex1_plain_text = :libsodium_crypto_aead_aes256gcm.decrypt(ex1_cipher_text <> ex1_cipher_tag, aad, ex1_iv, ex1_cek)
ex1_plain_text == plain_text # true
##############################################
# Example 2: Key-Wrap and Content Encryption #
##############################################
# In this example, the KEK must be known by the encryptor and decryptor (ie. a shared secret)
ex2_kek = "abcdefghijklmnopqrstuvwxyz012345" # 256-bit KEK (Key Encryption Key)
ex2_cek_size = byte_size(ex2_cek)
# The CEK and IV are randomly generated.
ex2_cek = :crypto.strong_rand_bytes(32) # 256-bit CEK (Content Encryption Key)
# <<95,58,207,36,53,149,81,144,216,233,152,161,104,175,182,11,94,117,232,14,126,254,255,211,227,16,71,210,184,161,189,73>>
ex2_iv = :crypto.strong_rand_bytes(12) # 96-bit IV (Initialization Vector)
# <<236,191,80,159,152,112,216,59,74,93,6,143>>
# Encrypting the Content (Plain Text).
<<
ex2_cipher_text::binary-size(plain_text_size),
ex2_cipher_tag::bitstring-size(128)
>> = :libsodium_crypto_aead_aes256gcm.encrypt(plain_text, aad, ex2_iv, ex2_cek)
# Encrypting the Key (CEK).
ex2_keaad = "protected data" # Key Encryption AAD
ex2_keiv = :crypto.strong_rand_bytes(12) # 96-bit Key Encryption IV
# <<135,77,248,38,180,99,161,101,213,38,222,250>>
<<
ex2_kecipher_text::binary-size(ex2_cek_size),
ex2_kecipher_tag::bitstring-size(128)
>> = :libsodium_crypto_aead_aes256gcm.encrypt(ex2_cek, ex2_keaad, ex2_keiv, ex2_kek)
# The following is intended to be publicly visible.
ex2_public = {aad, {ex2_keaad, ex2_keiv, ex2_kecipher_text, ex2_kecipher_tag}, ex2_iv, ex2_cipher_text, ex2_cipher_tag}
# {"A256GCM", {"protected data", <<135,77,248,38,180,99,161,101,213,38,222,250>>, <<13,227,164,40,197,50,28,239,55,199,255,102,103,49,114,57,183,12,238,77,72,240,171,12,247,232,250,232,20,23,248,108>>, <<100,176,185,203,201,196,190,6,6,55,79,231,58,234,121,38>>}, <<236,191,80,159,152,112,216,59,74,93,6,143>>, <<65,137,156,181>>, <<149,10,202,45,190,117,184,202,126,43,94,84,2,43,176,130>>}
# And here's the decryption of the key:
ex2_decrypted_cek = :libsodium_crypto_aead_aes256gcm.decrypt(ex2_kecipher_text <> ex2_kecipher_tag, ex2_keaad, ex2_keiv, ex2_kek)
ex2_decrypted_cek == ex2_cek # true
# And the decryption of the content:
ex2_plain_text = :libsodium_crypto_aead_aes256gcm.decrypt(ex2_cipher_text <> ex2_cipher_tag, aad, ex2_iv, ex2_decrypted_cek)
ex2_plain_text == plain_text # true
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment