Rails 필드 암호화 스토리지 구현

2725 단어 Rails
시나리오
저장 전, 암호화 후 데이터베이스에 저장
읽기 후 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, Hash
end

user = User.new
user.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
 end
end

class User < ActiveRecord::Base
 serialize :preferences, CustomerSerializer
end

이를 바탕으로 우리는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)
 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

개선할 수 있는 점
복호화 키의 사용은 너무 간단합니까?
기존 데이터에 대해 어떻게 부드럽게 전환합니까?

좋은 웹페이지 즐겨찾기