2
\$\begingroup\$

The task at hand was to ensure that certain columns in the database are encrypted in case the database data is stolen. I have a feeling that a lot can be improved here (naming, DSL, encapsulations) while keeping the functionality as simple as it is. Let me know what you think, I'd appreciate any suggestions and ideas!

application_record.rb

class ApplicationRecord < ActiveRecord::Base
  extend Encryptable
  #...
end

encryptable.rb

module Encryptable
  def encrypt_columns(*columns)
    columns.each do |column|
      if self.column_names.include?(column.to_s)
        define_method "#{column}=" do |value|
          self[column] = self.class.crypt.encrypt_and_sign(value)
        end

        define_method "#{column}" do
          self.class.crypt.decrypt_and_verify(self[column])
        end
      end
    end
  end

  def crypt
    salt = '"\xCA)P\x9Dbc\xF7\x85B\xF3v}*p\xA6~\xBAR\xC1K\xE3\x88\xB8\x18\xF7\xD1\xB6e0\x98\xEF \xB9%\xB3\x12\x9C\xFE,\x89\xF4\xDE\xED!:7\xAE<q\xB1.<~\xA3m\e\x8C\t\xCF&/3\xCE\xAE"'
    key = ActiveSupport::KeyGenerator.new('password').generate_key(salt)

    @crypt ||= ActiveSupport::MessageEncryptor.new(key)
  end
end

user.rb

class User < ApplicationRecord
  encrypt_columns :email, :social_security_number
end
\$\endgroup\$
  • 5
    \$\begingroup\$ Step 1: Don't hard-code your salt and password... \$\endgroup\$ – Flambino Aug 31 '16 at 15:44
1
\$\begingroup\$

Some notes:

  • The recommended way to overwrite accessors is to use super.

  • As @Flambino says, it's better not to hardcode secrets directly in the code. The can be in a configuration file not commited to the repository.

  • I'd write the crypt method this way:

    def crypt
      @crypt ||= begin
        key = ActiveSupport::KeyGenerator.new('password').generate_key('salt')    
        ActiveSupport::MessageEncryptor.new(key)
      end
    end
    
\$\endgroup\$
1
\$\begingroup\$

There is already a gem for encrypting data at rest. Does this work for you? https://github.com/attr-encrypted/attr_encrypted

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.