方案
存儲前,加密后再存儲到數據庫
讀取后,利用 KEY 進行解密
實現
ActiveSupport::MessageEncryptor 是 Rails 基于 openssl 封裝實現的一個類,可用于對一個對象進行加密、解密操作。例如:
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 是 Rails ActiveRecord 里的一個類方法,可用于執行一個 column 如何存儲到數據庫,以及從數據庫讀取出來后要如何處理,例如:
class User < ActiveRecord::Base serialize :preferences, Hashenduser = User.newuser.preferences = { gender: 'male', age: 18}user.save!
另外,Rails 還允許自定義 Serizlizer,使得開發者能夠自行決定如何做進行序列化和反序列化。例如:
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
基于此,我們可以自己實現一個 serializer,使得我們能夠進行對字段進行加密存儲,同時讀取出來時能夠自行進行解密。
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
可以改進的點
加解密用的 KEY 是否過于簡單?
針對現有數據,如何平滑過渡?
新聞熱點
疑難解答
圖片精選