Isso é ótimo quando você precisa de criptografia bidirecional para armazenar senhas de serviço externo.
gem 'gibberish'
module HasDecryptablePassword
SALT_LENGTH = 64
KEY_LENGTH = 64
# TODO move (and change) AES_KEY to secrets.yml
# AES_KEY will need to be known by all apps, i.e background jobs, etc.
AES_KEY = 'your-secret-key'
AES_SIZE = 256 # TODO 512 is not supported by gibberish gem, investigate
module ActiveModel
extend ActiveSupport::Concern
included do
include HasDecryptablePassword
validates :encrypted_password, presence: true
validates :salt, presence: true, length: {is: SALT_LENGTH}
before_validation :encrypt_password
end
end
def encrypt_password
self.encrypted_password = aes_cipher.enc(password)
true
end
def decrypted_password
aes_cipher.dec(encrypted_password)
end
private
def aes_cipher
Gibberish::AES.new(key, AES_SIZE)
end
def key
generate_salt
fail unless AES_KEY.length == KEY_LENGTH
fail unless salt.length == SALT_LENGTH
AES_KEY + salt
end
def generate_salt
self.salt ||= SecureRandom.hex(SALT_LENGTH >> 1)
end
end