View Source ExAws.S3.Crypto (ex_aws_s3_crypto v3.0.2)

ExAws.S3.Crypto provides client-side encryption support for Amazon S3. It allows you to encrypt data before sending it to S3. This particular implementation currently supports a AWS KMS-managed customer master key and assumes you have one already generated.

This library makes heavy use of the existing ex_aws_s3 library and Erlang's crypto module. It has confirmed compatability with the Golang AWS SDK client-encryption library and uses AES GCM with 256-bit keys by default.

Examples

First, make sure you have the id for your master key (should be of the form of a UUID, like 123e4567-e89b-12d3-a456-426655440000) and the bucket you're using already set up. You should be able to make requests using ExAws (see the ExAws docs for configuration instructions).

To encrypt and upload an object, it's easy as pie.

bucket = "my-awesome-bucket"
key_id = "123e4567-e89b-12d3-a456-426655440000"
contents = "this is some special text that should be secret"

# Encrypt, then upload object
request = ExAws.S3.put_object(bucket, "secret.txt.enc", contents)
{:ok, encrypted_request} = ExAws.S3.Crypto.encrypt(request, key_id)
ExAws.request(encrypted_request)

# Or, use this shorter version of above
ExAws.S3.Crypto.put_encrypted_object(bucket, "secret.txt.enc", contents, key_id)

Decrypting is easy too, and doesn't even require knowing the original key id.

# get encrypted object, then decrypt
{:ok, encrypted} = ExAws.S3.get_object(bucket, "secret.txt.enc") |> ExAws.request
{:ok, decrypted} = ExAws.S3.Crypto.decrypt(encrypted)
IO.puts decrypted.body

# Or, use this shorter version of above
{:ok, decrypted} = ExAws.S3.Crypto.get_encrypted_object(bucket, "secret.txt.enc")
IO.puts decrypted.body

Summary

Functions

Take the result of a ExAws.S3.get_object/3 and replace the body with the decrypted value.

Modify a ExAws.Operation.S3 put operation by encrypting the body with a key generated from KMS using the given master key_id.

Get an object from a bucket and then decrypt the body. This merely wraps sending a ExAws.S3.get_object/3 request and then calling decrypt/1 with the results.

Encrypt and then create an object within a bucket. This merely wraps creating a ExAws.Operation.S3 request, calling encrypt/3, and uploading to S3 via a call to ExAws.request/1.

Types

@type encrypt_opts() :: [{:cipher, supported_cipher()}]
@type supported_cipher() :: :aes_gcm

Functions

@spec decrypt(response :: term()) :: term()

Take the result of a ExAws.S3.get_object/3 and replace the body with the decrypted value.

For example:

bucket = "my-awesome-bucket"
key_id = "123e4567-e89b-12d3-a456-426655440000"

# get encrypted object, then decrypt
{:ok, encrypted} = ExAws.S3.get_object(bucket, "secret.txt.enc") |> ExAws.request
{:ok, decrypted} = ExAws.S3.Crypto.decrypt(encrypted)
IO.puts decrypted.body
Link to this function

encrypt(operation, key_id, opts \\ [])

View Source
@spec encrypt(
  operation :: ExAws.Operation.S3.t(),
  key_id :: binary(),
  opts :: encrypt_opts()
) ::
  ExAws.Operation.S3.t()

Modify a ExAws.Operation.S3 put operation by encrypting the body with a key generated from KMS using the given master key_id.

For example:

bucket = "my-awesome-bucket"
key_id = "123e4567-e89b-12d3-a456-426655440000"
contents = "this is some special text that should be secret"

# Encrypt, then upload object
request = ExAws.S3.put_object(bucket, "secret.txt.enc", contents)
{:ok, encrypted_request} = ExAws.S3.Crypto.encrypt(request, key_id)
ExAws.request(encrypted_request)
Link to this function

get_encrypted_object(bucket, object, opts \\ [])

View Source
@spec get_encrypted_object(
  bucket :: binary(),
  object :: binary(),
  opts :: ExAws.S3.get_object_opts()
) :: {:ok, term()} | {:error, term()}

Get an object from a bucket and then decrypt the body. This merely wraps sending a ExAws.S3.get_object/3 request and then calling decrypt/1 with the results.

For example:

{:ok, decrypted} = ExAws.S3.Crypto.get_encrypted_object("my-awesome-bucket", "secret.txt.enc")
IO.puts decrypted.body
Link to this function

put_encrypted_object(bucket, object, body, key_id, opts \\ [])

View Source
@spec put_encrypted_object(
  bucket :: binary(),
  object :: binary(),
  body :: binary(),
  key_id :: binary(),
  opts :: ExAws.S3.put_object_opts()
) :: {:ok, term()} | {:error, term()}

Encrypt and then create an object within a bucket. This merely wraps creating a ExAws.Operation.S3 request, calling encrypt/3, and uploading to S3 via a call to ExAws.request/1.

For example:

bucket = "my-awesome-bucket"
key_id = "123e4567-e89b-12d3-a456-426655440000"
contents = "this is some special text that should be secret"

ExAws.S3.Crypto.put_encrypted_object(bucket, "secret.txt.enc", contents, key_id)