我尝试使用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
答案 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