Skip to content

Instantly share code, notes, and snippets.

@leehambley
Last active October 21, 2019 16:58
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
Star You must be signed in to star a gist
Embed
What would you like to do?
#!/usr/bin/env ruby
IAM_ARNS = {
web_app: '...',
mobile_app: '...',
admin_app: '',
backups_script: '',
}
# Connect to KMS
kms_client = Aws::KMS::Client.new(
access_key_id: ENV['access_key_id'],
secret_access_key: ENV['secret_access_key']
# Data from user order process
user = OpenStruct.new({id: 123, name: "Lee", email: "lee...@example.com"})
order = OpenStruct.new({id: 456, user_id: 123, .....})
# Make KMS keys https://docs.aws.amazon.com/cli/latest/reference/kms/create-key.html
user_kms_key = kms_client.create_key({{
tags: [
{ tag_key: "kind", tag_value: "user", },
{ tag_key: "user_id", tag_value: user.id, },
],
}
order_kms_key = kms_client.create_key({{
tags: [
{ tag_key: "kind", tag_value: "order", },
{ tag_key: "user_id", tag_value: user.id, },
{ tag_key: "order_id", tag_value: order.id, },
],
}
# Make AES keys (this is what we ENCRYPT in KMS, our data is encrypted with this key
# and we never store it in cleartext)
user_cipher = OpenSSL::AES256.new(:CFB)
user_cipher.encrypt
user_aes_key = user_cipher.random_key
order_cipher = OpenSSL::AES256.new(:CFB)
order_cipher.encrypt
order_aes_key = order_cipher.random_key
# Ask KMS to encrypt our keys....
user_encrypted_aes_key = client.encrypt({
key_id: user_kms_key[:key_metadata][:arn],
plaintext: user_aes_key
})
order_encrypted_aes_key = client.encrypt({
key_id: order_kms_key[:key_metadata][:arn],
plaintext: order_aes_key
})
encrypted_user = user.merge(
user.slice(:name, :email, :etc, :etc).map do |field|
encrypt_field(field, user_aes_key)
end
user.merge({ # add encryption attrs
kms_arn: user_kms_key[:key_metadata][:arn],
rsa_key: user_encrypted_aes_key[:ciphertext_blob] # the encryption key, encrypted, thanks to KMS
})
)
encrypted_order = order.merge(
order.slice(:delivery_address, :contact_name, :etc, :etc).map do |field|
encrypt_field(field, order_aes_key)
end
order.merge({ # add encryption attrs
kms_arn: order_kms_key[:key_metadata][:arn],
rsa_key: order_encrypted_aes_key[:ciphertext_blob] # the encryption key, encrypted, thanks to KMS
})
)
# Ensure never to store user_rsa_key or order_rsa_key locally.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment