active record with ssl encryption
require 'openssl'
require 'digest/sha1'
require 'base64'
require 'json'
class Setting < ActiveRecord::Base
belongs_to :user, inverse_of: :settings
serialize :content, JSON
validates :user, presence: true
validates :name, presence: true, format: /\A[a-z0-9_\.]+\z/
@decrypted = nil
before_save do
@decrypted = content
self.content = encrypt(content)
end
after_save do
self.content = @decrypted
end
after_find do
self.content = decrypt(content)
end
private
def encrypt(content)
content = ActiveSupport::JSON.encode(content)
cipher = OpenSSL::Cipher::Cipher.new('aes-256-cbc')
cipher.encrypt
random_iv = cipher.random_iv
self.salt = Base64.encode64(random_iv)
cipher.key = crypt_key
cipher.iv = random_iv
encrypted = cipher.update(content)
encrypted << cipher.final
Base64.encode64(encrypted)
end
def decrypt(content)
content = Base64.decode64(content)
cipher = OpenSSL::Cipher::Cipher.new('aes-256-cbc')
cipher.decrypt
cipher.key = crypt_key
cipher.iv = Base64.decode64(salt)
decrypted = cipher.update(content)
decrypted << cipher.final
ActiveSupport::JSON.decode(decrypted)
end
def crypt_key
Digest::SHA1.hexdigest(ENV['APP_SETTINGS_SALT'])
end
end