Last active
July 8, 2021 09:35
-
-
Save mmyoji/a5fb0ba9ee3a40b2dc0597638edcb73d to your computer and use it in GitHub Desktop.
Reversible encryption in RoR
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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