Rails实现字段加密存储

 更新时间:2017年11月27日 08:56:42   作者:JustQyx   我要评论

这篇文章主要介绍了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

可以改进的点

加解密用的 KEY 是否过于简单?
针对现有数据,如何平滑过渡?

相关文章

  • 你应该知道的Ruby代码风格

    你应该知道的Ruby代码风格

    Ruby是非常自由灵活的语言,所以不同的Rubist风格差异可能很大。那么在代码规范方面他们的差异大不大呢? 通过分析GitHub上托管的开源代码,得出了 一些有趣的结果 ,让我们一起来看看Rubist的喜好吧
    2014-03-03
  • Ruby中遍历目录的简洁方法

    Ruby中遍历目录的简洁方法

    这篇文章主要介绍了Ruby中遍历目录的简洁方法,本文分享了一个复杂方法和一个简洁方法,需要的朋友可以参考下
    2015-01-01
  • ruby 学习笔记(2) 类的基本使用

    ruby 学习笔记(2) 类的基本使用

    ruby 学习笔记(2) 类的基本使用
    2010-02-02
  • Ruby self在不同环境的含义

    Ruby self在不同环境的含义

    Ruby的self在不同的环境中有不同的含义,这点和java的this不同,原因是java实际上只有一种环境--在class的实例方法定义中使用,代表访问这个方法参数自动传进的那个对象。
    2008-12-12
  • Ruby on Rails迁移时的一些注意事项

    Ruby on Rails迁移时的一些注意事项

    这篇文章主要介绍了Ruby on Rails迁移时的一些注意事项,包括建议的使用change方法取代up与down方法等细节,需要的朋友可以参考下
    2015-08-08
  • ruby实现github第三方认证

    ruby实现github第三方认证

    GitHub在用户认证过程中采用了双匙机制,在双匙加密机制中,只有合法用户才拥有私匙,只要GitHub在收到请求时可以证明提交请求的客户端上拥有该私匙,即可以确认该操作是由合法用户发起的。我们通过ruby来简单模拟下吧。
    2015-06-06
  • Ubuntu上配置Ruby on Rails框架及RubyMine IDE开发环境

    Ubuntu上配置Ruby on Rails框架及RubyMine IDE开发环境

    Ruby on Rails是Ruby世界中当仁不让的Web框架代表,甚至可以说Rails推动了Ruby的流行,这里我们就来看一下如何在Ubuntu上配置Ruby on Rails框架及RubyMine IDE开发环境
    2016-07-07
  • Ruby 中$开头的全局变量、内部变量、隐藏变量介绍

    Ruby 中$开头的全局变量、内部变量、隐藏变量介绍

    这篇文章主要介绍了Ruby 中$开头的全局变量、内部变量、隐藏变量介绍,需要的朋友可以参考下
    2014-04-04
  • Ruby实现的合并排序算法

    Ruby实现的合并排序算法

    这篇文章主要介绍了Ruby实现的合并排序算法,本文直接给出实现代码,需要的朋友可以参考下
    2015-05-05
  • Ruby 中一些百分号(%)的用法小结

    Ruby 中一些百分号(%)的用法小结

    这篇文章主要介绍了Ruby 中一些百分号(%)的用法小结,需要的朋友可以参考下
    2014-05-05

最新评论