Cryptonite
This gem enables the encryption of specific ActiveRecord attributes using public key encryption. The advantage is that write only operations do not require the presence of the private key and thus front-end machines will not expose encrypted data in the event of a security breach.
Of course you are as safe as your encryption algorithm and key, so no guarantees there. Moreover, this library acts as a front-end to OpenSSL API of the Ruby standard library, which handles the encryption, and should not be considered as cryptography software.
Installation
Add this line to your application's Gemfile:
gem 'cryptonite'
And then execute:
$ bundle
Usage
Cryptonite adds to ActiveRecord the attr_encrypted
method, which is used to declare
the attributes that will be transparently encrypted, e.g.
attr_encrypted :secret, :another_secret
The library operates by serializing the fields with a custom encoder that will do encryption / decryption of the attribute value.
In order to encrypt the data the library should be provided with the public key
path, and respectively in order to decrypt them it requires the private key
path along with its password. Those settings can be set either in the
environment, using the variable names PUBLIC_KEY
, PRIVATE_KEY
and
PRIVATE_KEY_PASSWORD
, or be passed as options to the attr_encrypted
method:
attr_encrypted :secret, public_key: File.read('public_key.pem')
attr_encrypted :another_secret, private_key: 'private_key.pem', private_key_password: 'test'
attr_encrypted :yet_another_secret, key_pair: :get_key_method
If an application does not need to retrieve the encrypted information it is not required for the private key settings to be defined. Moreover, please note that ActiveRecord methods that operate massively on records do not use the serialization features and so encryption / decryption does not take place there. This is by design.
Note: Currently the independency on private key is not fully implemented.
Migration Helpers
In order to facilitate migration two module methods have been implemented that
operate independently from the ActiveRecord models. In a migration file the
Cryptonite.encrypt_model_attributes
may be used to facilitate upwards
migration and Cryptonite.decrypt_model_attributes
for downwards migration.
The parameters is the ActiveRecord model class and the exact same parameters as
the attr_encrypted
method, e.g.
class ChangeSecretInUsers < ActiveRecord::Migration
def up
change_column :users, :secret, :text, limit: 4096
say_with_time "encrypt_user_secrets" do
Cryptonite.encrypt_model_attributes(User, :secret, keypair: 'private_key.pem', private_key_password: 'test')
end
end
def down
say_with_time "decrypt_user_secrets" do
Cryptonite.decrypt_model_attributes(User, :secret, keypair: 'private_key.pem', private_key_password: 'test')
end
change_column :users, :secret, :string
end
end
Key Generation
Generate a key pair:
openssl genrsa -des3 -out private.pem 2048
Generating RSA private key, 2048 bit long modulus
......+++
.+++
e is 65537 (0x10001)
Enter pass phrase for private.pem:
Verifying - Enter pass phrase for private.pem:
and extract the the public key:
openssl rsa -in private.pem -out public.pem -outform PEM -pubout
Enter pass phrase for private.pem:
writing RSA key
Contributing
- Fork it ( https://github.com/GaggleAMP/cryptonite/fork )
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create a new Pull Request