5

我正在使用 attr_encrypted 来加密我的一些模型字段,并且我使用 Tire 和 Elasticsearch 进行全文搜索。我只使用一个简单的搜索表单。这是我的模型的一部分:

class Student < ActiveRecord::Base

  include Tire::Model::Search
  include Tire::Model::Callbacks

  attr_accessible :name, :surname
  attr_encrypted :name,             :key => 'f98gd9regre9gr9gre9gerh'
  attr_encrypted :surname,          :key => 'f98gd9regre9gr9gre9gerh'

  def self.search(params)
    tire.search(load: true) do
      query { string Student.encrypt_name(params[:search]) } if params[:search].present?
    end  
  end
end

因此,例如,如果我在数据库中有名称“John”,当我搜索“John”时,查询会在查询数据库之前被加密 (Student.encrypt_name(params[:search])),并返回结果. Elasticsearch 允许通配符搜索,例如如果我搜索“Joh*”,应该返回匹配的结果,但是加密的关键字“Joh”与加密的“John”不同,db 不返回任何结果。对此的任何解决方案将不胜感激。

问候, 拉多斯拉夫

4

2 回答 2

2

简答 - 全文搜索和客户端加密在当前最先进的技术中是相互排斥的。

更长的答案:

  1. 您还可以将明文存储在名称的soundex中并进行比较。这需要在功能和安全性方面做出妥协。检查它是什么并自己判断。

  2. 将加密的名称的所有可能部分匹配(或至少其中一些合理的子集)存储在单独的表中,并按身份匹配(可能与加密数据一起)。不适合我,但如果你喜欢冒险,你可以在谷歌上搜索“数据散列”和“反向索引”。请注意,这也会损害安全性。

  3. 有理论上的结果,但我还没有发现任何接近实现的东西。

于 2012-12-11T11:43:06.513 回答
0

如果您的数据相对较小,另一种选择是将数据缓存在服务器内存中,并对缓存的数据集执行正则表达式匹配操作。如果出现以下情况,这可能是有意义的:

  1. 每所学校大约有 1000 名学生
  2. 你的缓存键是这样的,一个给定的学校只能在它的学生中搜索
  3. 您缓存搜索所需的最小字段集,而无需序列化整个对象

当然,黑客可能会访问您的网络服务器内存并读取数据。这可以通过精心设计的缓存刷新策略部分缓解。

于 2013-04-19T17:07:32.337 回答