Rails:访问序列化程序内部的记录实例

时间:2015-09-03 17:31:15

标签: ruby-on-rails security encryption

我尝试使用rails中的自定义列序列化程序加密某些JSON数据。因为加密需要是可逆的,所以我使用带有密钥和初始化向量(IV)的AES 256 CBC。

我希望key和iv对于每个记录都是唯一的,这些记录具有提供这两个值的实例方法。我现在遇到的问题是我无法访问序列化器/编码器内部的记录实例,因此我不确定如何将这些值传递给它。

这里有一些伪代码:

class MyModel
  serialize :keys, EncryptedJSON

  def data_encryption_key
    Digest::SHA2.new(256).hexdigest("#{user.id}:#{user.created_at.utc.to_i}:#{ENV["SOME_SECRECT_KEY_VALUE"]}")
  end

  def data_encryption_iv
    Digest::SHA2.new(256).hexdigest(user.created_at.utc.to_i)
  end
end

class EncryptedJSON
  require 'openssl'

  # decode, decrypt and convert to json
  def self.load(encrypted)
    return if encrypted.nil?

    decipher = OpenSSL::Cipher::AES.new(256, :CBC)

    decipher.decrypt

    # I want this to use: record.data_encryption_key()
    decipher.key = Digest::SHA2.new(256).hexdigest("123") 

    # I want this to use: record.data_encryption_iv()
    decipher.iv = Digest::SHA2.new(256).hexdigest("123") 

    encrypted = Base64.decode64(encrypted)
    decrypted = decipher.update(encrypted) + decipher.final

    JSON.parse(decrypted)
  end

  # convert to string, encrypt and encode
  def self.dump(data)
    return if data.nil?

    cipher = OpenSSL::Cipher::AES.new(256, :CBC)

    cipher.encrypt

    # I want this to use: record.data_encryption_key()
    cipher.key = Digest::SHA2.new(256).hexdigest("123")

    # I want this to use: record.data_encryption_iv()
    cipher.iv = Digest::SHA2.new(256).hexdigest("123") 

    encrypted = cipher.update(data.to_s) + cipher.final

    Base64.encode64(encrypted)
  end
end

1 个答案:

答案 0 :(得分:0)

不幸的是,由于serialize是一个类方法,因此无法将引用传递给实例。为了做你需要做的事情,你将不得不通过覆盖密钥的getter和setter方法来手动处理序列化和反序列化。

class MyModel < ActiveRecord::Base
  def keys=(json)
    write_attribute(:keys, EncryptedJSON.dump(json, self))
  end

  def keys
    EncryptedJSON.load(read_attribute(:keys), self)
  end
end