Rails實(shí)現(xiàn)字段加密存儲(chǔ)
方案
存儲(chǔ)前,加密后再存儲(chǔ)到數(shù)據(jù)庫(kù)
讀取后,利用 KEY 進(jìn)行解密
實(shí)現(xiàn)
ActiveSupport::MessageEncryptor 是 Rails 基于 openssl 封裝實(shí)現(xiàn)的一個(gè)類,可用于對(duì)一個(gè)對(duì)象進(jìn)行加密、解密操作。例如:
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 里的一個(gè)類方法,可用于執(zhí)行一個(gè) column 如何存儲(chǔ)到數(shù)據(jù)庫(kù),以及從數(shù)據(jù)庫(kù)讀取出來(lái)后要如何處理,例如:
class User < ActiveRecord::Base serialize :preferences, Hash end user = User.new user.preferences = { gender: 'male', age: 18 } user.save!
另外,Rails 還允許自定義 Serizlizer,使得開(kāi)發(fā)者能夠自行決定如何做進(jìn)行序列化和反序列化。例如:
class CustomerSerializer def self.load(value) value.to_s.blank? ? "" : JSON.parse(value) end def self.dump(value) (value || {}).to_json end end class User < ActiveRecord::Base serialize :preferences, CustomerSerializer end
基于此,我們可以自己實(shí)現(xiàn)一個(gè) serializer,使得我們能夠進(jìn)行對(duì)字段進(jìn)行加密存儲(chǔ),同時(shí)讀取出來(lái)時(shí)能夠自行進(jìn)行解密。
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) end end class 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, EncryptedStringSerializer end
可以改進(jìn)的點(diǎn)
加解密用的 KEY 是否過(guò)于簡(jiǎn)單?
針對(duì)現(xiàn)有數(shù)據(jù),如何平滑過(guò)渡?
相關(guān)文章
Ruby設(shè)計(jì)模式編程中使用Builder建造者模式的實(shí)例
這篇文章主要介紹了Ruby設(shè)計(jì)模式編程中使用Builder建造者模式的實(shí)例,建造者模式將一個(gè)復(fù)雜對(duì)象的構(gòu)造與它的表示分離,使同樣的構(gòu)建過(guò)程可以創(chuàng)建不同的表示,需要的朋友可以參考下2016-03-03Ruby中嵌套對(duì)象轉(zhuǎn)換成json的方法
這篇文章主要介紹了Ruby中嵌套對(duì)象轉(zhuǎn)換成json的方法,同時(shí)介紹了普通對(duì)象to_json的方法,需要的朋友可以參考下2014-06-06