PorkyLib
This gem is a cryptographic services library. PorkyLib uses AWS Key Management Service (KMS) for key management and RbNaCl for performing cryptographic operations.
Installation
Add this line to your application's Gemfile:
gem 'porky_lib'
And then execute:
$ bundle install
Or install it yourself as:
$ gem install porky_lib
Inside of your Ruby program do:
require 'porky_lib'
... to pull it in as a dependency.
Usage
Initialization
Something like the following should be included in an initializer in your Rails project:
# Use PorkyLib's AWS KMS mock client except in production, for example
use_mock_client = !Rails.env.production?
PorkyLib::Config.configure(aws_region: ENV[AWS_REGION],
aws_key_id: ENV[AWS_KEY_ID],
aws_key_secret: ENV[AWS_KEY_SECRET],
aws_client_mock: use_mock_client)
PorkyLib::Config.initialize_aws
Creating a New CMK
To create a new customer master key (CMK) within AWS:
# Where tags is a list of key/value pairs (i.e [{ key1: 'value1' }])
# key_alias is an optional parameter, and if provided will create an alias with the provided value for the newly created key
# key_rotation_enabled is an optional parameter, and if true will enable automatic key rotation for the new created key. Default is true.
key_id = PorkyLib::Symmetric.instance.create_key(, key_alias, key_rotation_enabled)
Creating an Alias for an Existing CMK
To create a new alias for an existing customer master key (CMK) within AWS:
# Where key_id is the AWS key ID or Amazon Resource Name (ARN)
# key_alias is the value of the alias to create
PorkyLib::Symmetric.instance.create_alias(key_id, key_alias)
Enabling Key Rotation for an Existing CMK
To create a new alias for an existing customer master key (CMK) within AWS:
# Where key_id is the AWS key ID or Amazon Resource Name (ARN)
PorkyLib::Symmetric.instance.enable_key_rotation(key_id)
Encrypting Data
To encrypt data:
# Where data is the data to encrypt
# cmk_key_id is the AWS key ID, Amazon Resource Name (ARN) or alias for the CMK to use to generate the data encryption key (DEK)
# ciphertext_dek is an optional parameter to specify the data encryption key to use to encrypt the data. If not provided, a new data encryption key will be generated. Default is nil.
# encryption_context is an optional parameter to provide additional authentication data for encrypting the DEK. Default is nil.
[ciphertext_dek, ciphertext, nonce] = PorkyLib::Symmetric.instance.encrypt(data, cmk_key_id, ciphertext_dek, encryption_context)
Decrypting Data
To decrypt data:
# Where ciphertext_dek is the encrypted data encryption key (DEK)
# ciphertext is the encrypted data to be decrypted
# nonce is the nonce value associated with ciphertext
# encryption_context is an optional parameter to provide additional authentication data for decrypting the DEK. Default is nil. Note, this must match the value that was used to encrypt.
plaintext_data = PorkyLib::Symmetric.instance.decrypt(ciphertext_dek, ciphertext, nonce, encryption_context)
Generating Data Encryption Keys
To generate a new data encryption key:
# Where cmk_key_id is the AWS key ID, Amazon Resource Name (ARN) or alias for the CMK to use to generate the data encryption key (DEK)
# encryption_context is an optional parameter to provide additional authentication data for encrypting the DEK. Default is nil.
plaintext_key, ciphertext_key = PorkyLib::Symmetric.instance.generate_data_encryption_key(cmk_key_id, encryption_context)
Decrypting Data Encryption Keys
To decrypt an existing ciphertext data encryption key:
# Where ciphertext_key is the data encryption key, encrypted by a CMK within your AWS environment.
# encryption_context is an optional parameter to provide additional authentication data for encrypting the DEK. Default is nil.
plaintext_key = PorkyLib::Symmetric.instance.generate_data_encryption_key(ciphertext_key, encryption_context)
Securely Deleting Plaintext Key From Memory
To securely delete the plaintext key from memory:
# Where length is the number of bytes of the plaintext key (i.e. plaintext_key.bytesize)
plaintext_key.replace(PorkyLib::Symmetric.instance.secure_delete_plaintext_key(plaintext_key.bytesize))
Check If An Alias Exists
To verify whether an alias exists or not:
# Where key_alias is the alias name to verify
alias_exists = PorkyLib::Symmetric.instance.cmk_alias_exists?(key_alias)
To Read From AWS S3
# Where bucket_name is the name of the S3 bucket to read from
# file_key is file identifier of the file/data that was written to S3.
file_data = PorkyLib::FileService.read(bucket_name, file_key)
To Write To AWS S3
# Where file is the data to encrypt and upload to S3 (can be raw data or path to a file on disk)
# bucket_name is the name of the S3 bucket to write to
# key_id is the ID of the CMK to use to generate a data encryption key to encrypt the file data
# options is an optional parameter for specifying optional metadata about the file
file_key = PorkyLib::FileService.write(file, bucket_name, key_id, )
Development
Development on this project should occur on separate feature branches and pull requests should be submitted. When submitting a pull request, the pull request comment template should be filled out as much as possible to ensure a quick review and increase the likelihood of the pull request being accepted.
Running Tests
rspec # Without code coverage
COVERAGE=true rspec # with code coverage
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/Zetatango/porky_lib