Module: Pod4::Encrypting

Defined in:
lib/pod4/encrypting.rb

Overview

A mixin to give you basic encryption, transparently.

Example


class Foo < Pod4::Model
  include Pod4::Encrypting

  set_key           $encryption_key
  set_iv_column     :nonce
  encrypted_columns :one, :two, :three

  ...
end

So, this adds ‘set_key`, `set_iv_column`, and `encrypted_columns` to the model DSL. Only `set_iv_column` is optional, and it is highly recommended.

set_key


Can be any string you like, but should ideally be long and random. If it’s not long enough you will get an exception. The key is used for all encryption on the model.

You probably have a single key for the entire database and pass it to your application via an environment variable. But we don’t care about that.

If you set the key to nil, then the model should work exactly as if the encryption mixin was not present.

set_iv_column


The name of a text column on the table which holds the initialisation vector, or nonce, for the record. IVs don’t have to be secret, but they should be different for each record; we take care of creating them for you.

If you don’t provide an IV column, then we fall back to insecure ECB mode for the encryption. Don’t make us do that.

encrypted_columns


The list of columns to encrypt. In addition, it acts just the same as attr_columns, so you can name the column there too, or not. Up to you.

Changes to Behaviour of Model


‘map_to_interface`: data going from the model to the interface has the relevant columns encrypted. If the IV column is nil, we set it to a good IV.

‘map_to_model`: data going from the interface to the model has the relevant columns decrypted.

Assumptions / limitations:

  • One key for all the data in the model.

  • a column on the table holding an initiation vector (IV, nonce) for each record. See above.

  • we only store encrypted data in text columns, and we can’t guarantee that the encrypted data will be the same length as when unencrypted.

Additional Methods


You will almost certainly never need to use these.

  • ‘encryption_iv` returns the value of the IV column of the record, whatever it is.

  • ‘encrypt` and `decrypt` allow you to transform arbitrary text in a manner compatible with the model – for example, if you removed a column from `encrypted_columns`, you could do a one-time decrypt of your data.

Notes


Encryption is provided by OpenSSL::Cipher. For more information, you should read the official Ruby docs for this; they are really helpful.

Defined Under Namespace

Modules: ClassMethods, InstanceMethods

Constant Summary collapse

CIPHER_IV =
"AES-128-CBC"
CIPHER_NO_IV =
"AES-128-ECB"

Class Method Summary collapse

Class Method Details

.included(base) ⇒ Object

A little bit of magic, for which I apologise.

When you include this module it actually adds the methods in ClassMethods to the class as if you had called ‘extend Encrypting:ClassMethds` AND adds the methods in InstanceMethods as if you had written `prepend Encrypting::InstanceMethods`.

In my defence: I didn’t want to have to make you remember to do that…



104
105
106
107
# File 'lib/pod4/encrypting.rb', line 104

def self.included(base)
  base.extend  ClassMethods
  base.send(:prepend, InstanceMethods)
end