Rails implements field encryption storage and rails field Encryption
Solution
Data is encrypted before being stored in the database.
The KEY is used for decryption after reading.
Implementation
ActiveSupport: MessageEncryptor is a class implemented by Rails Based on openssl encapsulation. It can be used to encrypt and decrypt an object. For example:
salt = SecureRandom.random_bytes(64)key = ActiveSupport::KeyGenerator.new('password').generate_key(salt) # => "\x89\xE0\x156\xAC..."crypt = ActiveSupport::MessageEncryptor.new(key) # => #<ActiveSupport::MessageEncryptor ...>encrypted_data = crypt.encrypt_and_sign('my secret data') # => "NlFBTTMwOUV5UlA1QlNEN2xkY2d6eThYWWh..."crypt.decrypt_and_verify(encrypted_data) # => "my secret data"
Serialize is a class method in Rails ActiveRecord. It can be used to execute how a column is stored in the database and how to handle it after it is read from the database. For example:
class User < ActiveRecord::Base serialize :preferences, Hashenduser = User.newuser.preferences = { gender: 'male', age: 18}user.save!
In addition, Rails allows custom Serizlizer, allowing developers to determine how to perform serialization and deserialization on their own. For example:
class CustomerSerializer def self.load(value) value.to_s.blank? ? "" : JSON.parse(value) end def self.dump(value) (value || {}).to_json endendclass User < ActiveRecord::Base serialize :preferences, CustomerSerializerend
Based on this, we can implement a serializer by ourselves, so that we can encrypt and store fields and decrypt the fields when reading them.
class EncryptedStringSerializer def self.load(value) value.to_s.blank? ? '' : decrypt(value) end def self.dump(value) encrypt(value || '') end private def self.encrypt(value) encryptor.encrypt_and_sign(value) end def self.decrypt(value) encryptor.decrypt_and_verify(value) end def self.encryptor @encryptor ||= ActiveSupport::MessageEncryptor.new(Settings.message_encryptor_key) endendclass UserAddress < ActiveRecord::Base serialize :phone, EncryptedStringSerializer serialize :first_name, EncryptedStringSerializer serialize :last_name, EncryptedStringSerializer serialize :country, EncryptedStringSerializer serialize :state, EncryptedStringSerializer serialize :city, EncryptedStringSerializer serialize :address1, EncryptedStringSerializer serialize :address2, EncryptedStringSerializer serialize :zipcode, EncryptedStringSerializerend
Improvements
Is the KEY used for encryption and decryption too simple?
How can we smoothly transition existing data?