Every repository with this icon (
Every repository with this icon (
| name | age | message | |
|---|---|---|---|
| |
CHANGELOG | Fri Jun 06 11:38:28 -0700 2008 | [shuber] |
| |
MIT-LICENSE | Sun Apr 27 21:33:47 -0700 2008 | [Sean Huber] |
| |
README.markdown | Fri Jun 06 11:38:28 -0700 2008 | [shuber] |
| |
Rakefile | Sun Apr 27 21:33:47 -0700 2008 | [Sean Huber] |
| |
init.rb | Fri Jun 06 11:29:32 -0700 2008 | [shuber] |
| |
lib/ | Fri Jun 06 11:29:32 -0700 2008 | [shuber] |
| |
tasks/ | Sun Apr 27 21:33:47 -0700 2008 | [Sean Huber] |
| |
test/ | Fri Jun 06 11:29:32 -0700 2008 | [shuber] |
Huberry::AttrEncrypted
An INCOMPLETE ActiveRecord plugin that encrypts/decrypts attributes transparently for secure database storage. It uses the standard ruby OpenSSL library by default, but can also be configured to use custom encryption classes and algorithms.
Installation
script/plugin install git://github.com/shuber/attr_encrypted
Note
This plugin sets encryption settings at the class level which means that you can't uniquely encrypt each row in a table (like storing a custom salt for each record), however this allows you to perform query searches on encrypted fields. For example: User.find_by_email('shuber@huberry.com') would still work.
Usage
Basic
Let's suppose a users table has the following fields: encrypted_email, encrypted_credit_card, first_name, last_name. You would setup the model like so:
class User < ActiveRecord::Base
attr_encrypted :email, :credit_card, :key => 'some_super_secret_encryption_key'
end
You can now use the attribute accessors "email" and "credit_card" to manipulate the encrypted fields.
u = User.new
u.email # nil
u.encrypted_email # ""
u.email = 'test@test.com'
u.encrypted_email # ""
u.save
u.encrypted_email # "\x96\x8E|\x13\x16BU\xC1\x10\xBCk\xA1\x10=\x87\x85"
u = User.find_by_email('test@test.com')
u.email # "test@test.com"
u.encrypted_email # "\x96\x8E|\x13\x16BU\xC1\x10\xBCk\xA1\x10=\x87\x85"
For your convenience, a call to attr_protected is placed for each of the encrypted fields automatically.
Special attribute names
By default, the plugin assumes that the real attribute name for each attr_accessor that it creates is "encrypted_#{attr}" If this is not the case, you can specify the real attribute name in the optional :attr_names hash. Let's suppose instead of having an encrypted_email field, your table has a secret_email field. You would then set up the model like so:
class User < ActiveRecord::Base
attr_encrypted :email, :credit_card, :key => 'some_super_secret_encryption_key', :attr_names => { :email => :secret_email }
end
Everything should work correctly now.
u = User.new
u.email = 'test@test.com'
u.save
u.secret_email # "\x96\x8E|\x13\x16BU\xC1\x10\xBCk\xA1\x10=\x87\x85"
Unique encryption keys for each attribute
Let's suppose that you'd like to be extra safe and encrypt each of the attributes with a different encryption key. Simply set up your model like so:
class User < ActiveRecord::Base
attr_encrypted :email, :key => 'some_super_secret_encryption_key'
attr_encrypted :credit_card, :key => 'some_other_super_secret_key'
end
Specifying the encryption algorithm
This plugin's default encryptor wraps the standard ruby OpenSSL library and can be configured to use the following algorithms: AES128, AES192, AES256, BF, CAST5, DES, IDEA, RC2, RC4, RC5. The BF algorithm is used by default, but if you'd like to change it, just set up your model like so:
class User < ActiveRecord::Base
attr_encrypted :email, :credit_card, :key => 'some_super_secret_encryption_key', :encryptor_options => { :algorithm => 'RC5' }
end
You can even specify a different encryption algorithm for each attribute like so:
class User < ActiveRecord::Base
attr_encrypted :email, :key => 'some_super_secret_encryption_key', :encryptor_options => { :algorithm => 'RC5' }
attr_encrypted :credit_card, :key => 'some_other_super_secret_key', :encryptor_options => { :algorithm => 'DES' }
end
Encoding
By default, attr_encrypted will automatically base64 encode/decode the encrypted values so that it stores correctly with most database field types. To disable this behavior, simply add this option:
class User < ActiveRecord::Base
attr_encrypted :email, :key => 'some_super_secret_encryption_key', :use_encoding => false
end
Custom encryption algorithms
You may use other encryption algorithms that are not included in the standard ruby OpenSSL library by specifying an :encryptor_class, :encrypt_method, and :decrypt_method in the attr_encrypted method call.
Lets suppose you'd like to use this custom encryption class:
class SillyEncryptor
def self.silly_encrypt(value, key, options = {})
(value + key).reverse
end
def self.silly_decrypt(value, key, options = {})
value.reverse.gsub(/key/, '')
end
end
To use this class with the example above, you would set up the model like so:
class User < ActiveRecord::Base
attr_encrypted :email, :credit_card, :key => 'some_super_secret_encryption_key',
:encryptor_class => SillyEncryptor,
:encrypt_method => :silly_encrypt,
:decrypt_method => :silly_decrypt
end
The plugin will pass these 3 arguments (in order) to the :encrypt_method and :decrypt_method of the :encryptor_class
value - The string to encrypt/decrypt
key - The encryption key
options - Any options you pass through :encryptor_options (see below)
You can specify the :options by passing :encryptor_options to the attr_encrypted method like so:
class User < ActiveRecord::Base
attr_encrypted :email, :credit_card, :key => 'some_super_secret_encryption_key',
:encryptor_class => SillyEncryptor,
:encrypt_method => :silly_encrypt,
:decrypt_method => :silly_decrypt,
:encryptor_options => { :some_custom_option => 'Some value' }
end
Finding records by an encrypted field
To retrieve records by an encrypted field, you can use the find_by_ or find_all_by_ class methods generated by this plugin. For the example above you would use:
User.find_by_email('test@test.com')
User.find_by_credit_card('1234 5678 1234 5678')
You may also pass a hash of options to it just like all the other find_by_ methods that are included in Rails.
User.find_by_email('test@test.com', :conditions => '...', :order => '...')
You can even search by a combination of fields
User.find_by_email_and_credit_card('test@test.com', '1234 5678 1234 5678')
Even a mix of encrypted/non-encrypted fields
User.find_by_email_and_first_name('shuber@huberry.com', 'sean')
Default options
You can override the default attr_encrypted options by setting values in the attr_encrypted_options hash
ActiveRecord::Base.attr_encrypted_options = {
:key => 'some_secret_key',
:encryptor_options = {
:algorithm => 'DES'
}
}
Then you can have clearer class definitions
Class User < ActiveRecord::Base
attr_encrypted :email
end
Methods generated by this plugin
This plugin generates 8 methods for each attribute that you encrypt with it:
Model.find_by_#{attribute}(value [, options])
Model.find_all_by_#{attribute}(value [, options])
Model.encrypt_#{attribute}(value) # aliased to one of the two methods below depending on the :use_encoding option
Model.encrypt_#{attribute}_with_encoding(value)
Model.encrypt_#{attribute}_without_encoding(value)
Model.decrypt_#{attribute}(value) # aliased to one of the two methods below depending on the :use_encoding option
Model.decrypt_#{attribute}_with_encoding(value)
Model.decrypt_#{attribute}_without_encoding(value)
For the example above, the plugin would generate the following methods for the email attribute:
User.find_by_email(value [, options])
User.find_all_by_email(value [, options])
User.encrypt_email(value)
User.encrypt_email_with_encoding(value)
User.encrypt_email_without_encoding(value)
User.decrypt_email(value)
User.decrypt_email_with_encoding(value)
User.decrypt_email_without_encoding(value)
Contact
Problems, comments, and suggestions all welcome: shuber@huberry.com




