Skip to content

Instantly share code, notes, and snippets.

@mmyoji
Last active July 8, 2021 09:35
Show Gist options
  • Save mmyoji/a5fb0ba9ee3a40b2dc0597638edcb73d to your computer and use it in GitHub Desktop.
Save mmyoji/a5fb0ba9ee3a40b2dc0597638edcb73d to your computer and use it in GitHub Desktop.
Reversible encryption in RoR
# frozen_string_literal: true
# Use Active Record Encryption for newer version of Rails
# https://edgeguides.rubyonrails.org/active_record_encryption.html
module ReversibleEncryptedAttribute
extend ActiveSupport::Concern
COLUMN_PREFIX = "encrypted"
class_methods do
# @param key [Symbol,String]
def encrypted_attribute(key)
column_name = "#{COLUMN_PREFIX}_#{key}"
# @param value [String,nil]
define_method "#{key}=" do |value|
public_send("#{column_name}=", encrypt(value))
end
# @return [String,nil]
define_method key do
return unless public_send("#{column_name}?")
decrypt(public_send(column_name))
end
end
end
private
def encryptor
@encryptor ||= ActiveSupport::MessageEncryptor.new(encryption_key)
end
def encrypt(value)
return if value.blank?
encryptor.encrypt_and_sign(value)
end
def decrypt(encrypted)
encryptor.decrypt_and_verify(encrypted)
end
# Must be 32 bytes
def encryption_key
raise "#{__method__} should be implemented."
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment