Skip to content

Rails plugin to encrypt/decrypt columns of ActiveRecord models with GPGME

License

Notifications You must be signed in to change notification settings

credil/acts_as_encrypted_with_gpgme

 
 

Repository files navigation

== ActsAsEncryptedWithGpgme

acts_as_encrypted_with_gpgme is a rails plugin which does
encryption/decryption with the GPGME (GnuPG Made Easy) library.

The main advantage of this plugin is that it stores encrypted data in
the standard OpenPGP format, while similar plugins use custom data
format.  Using the standard format allows you to easily migrate from
some crypto algorithm to the other algorithms.

== Usage

acts_as_encrypted_with_gpgme is capable of encrypting data with either
a public-key cipher or a symmetric cipher.

=== Using a public-key cipher

To use public-key cipher algorithm, you need a key pair for
encryption; the keys are loaded from
<tt>RAILS_ROOT/config/gpgme</tt>.

To generate a new key pair, do:

 $ mkdir config/gpgme
 $ gpg --homedir config/gpgme --gen-key
 ...follow the instruction prompted by gpg...

Now you have a key pair.  You might want to control detail behavior of
encryption through <tt>RAILS_ROOT/config/gpgme/gpg.conf</tt>.  For
example, to specify a cipher algorithm being used internally, add the
following line to the file:

 cipher-algo TWOFISH

For other options, see <tt>man gpg</tt>.

Now let's go ahead to create an ActiveRecord model.

 $ ./script/generate model account name:string credit_card_number:string
 $ rake db:migrate

Create app/models/account.rb containing the following:

 class Account < ActiveRecord::Base
   acts_as_encrypted_with_gpgme :fields => {
     :credit_card_number => {
       :recipients => ['AC5C76C1'] # key ID for the key generated above
     }
   }
 end

The above code means that the column named <i>credit_card_number</i>
be encrypted to a public-key identified by 'AC5C76C1'.  Note that at
this point the example only does *not* provide decryption---in other
words, the column <i>credit_card_number</i> is regarded as write-only
within your Rails application.

To make the column be decrypted after the data is retrieved from the
database, specify decryption key with the <tt>:key</tt> option:

 class Account < ActiveRecord::Base
   acts_as_encrypted_with_gpgme :fields => {
     :credit_card_number => {
       :recipients => ['AC5C76C1'] # key ID for the key generated above
       :key => 'AC5C76C1'
     }
   }
 end

and provide the passphrase to unlock the key; add the following to
<tt>config/initializers/gpgme.rb</tt>:

 ActsAsEncryptedWithGpgme.set_passphrase('AC5C76C1', 'your passphrase')

==== Selective encryption

One useful situation where you use asymmetric encryption is that your front
end collects sensitive information (e.g. credit card info, Census data, etc.)
and then encrypts to a public key and stores it.  The front end does not have
the private key available and so even a complete compromise gains nothing
other than the data currently being transacted (which is in memory).

On another machine, offline, with the private key loaded, one can then set
the :key field.   If you want to do this selectively, such as
if $GPG_AGENT_INFO is set, then set "auto_decrypt => false", and the
encrypted fields will not be decrypted until you explicitely do the work:

    pw = if ENV['GPG_AGENT_INFO']
           begin
             GPGME::decrypt(GPGME::Data.new(sip_password), nil)
           rescue GPGME::Error::NoData
             'emptypw'
           rescue
             'brokenpw'
           end
         else
           'fakepw'
         end

=== Using a symmetric cipher

Symmetric encryption can be used in the same way as public-key
encryption described in the previous section, except that you don't
need to prepare keys.  Let's start from creating models:

 $ ./script/generate model post title:string body:text
 $ rake db:migrate

Create app/models/post.rb containing the following:

 class Post < ActiveRecord::Base
   acts_as_encrypted_with_gpgme :fields => [:body]
 end

To tell the passphrase, add the following to
<tt>config/initializers/gpgme.rb</tt>:

 ActsAsEncryptedWithGpgme.set_passphrase('Post#body', 'your passphrase')

By default, the key for the passphrase is automatically constructed
from the class and the column name to be encrypted.

== Security consideration

It is generally not a good idea to hold a secret in memory for a long
time.  If you really want to support on-the-fly decryption, you should
probably consider hosting your Rails application on a trusted machine
isolated from the database server.

Copyright (c) 2009 Daiki Ueno, released under the MIT license

About

Rails plugin to encrypt/decrypt columns of ActiveRecord models with GPGME

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Ruby 100.0%