我正在使用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 不返回任何结果。对此的任何解决方案将不胜感激。
问候拉多斯拉夫
简短回答 - 全文搜索和客户端加密在当前最先进的技术水平下是相互排斥的。
更长的答案:
-
您还可以将明文存储名称的声音并进行比较。这需要在功能和安全性方面做出妥协。检查它是什么并自己判断。
-
将加密的名称的所有可能的部分匹配(或至少其中一些合理的子集)存储在单独的表中,并按标识匹配(可能使用加密数据)。不行,但如果你喜欢冒险,你可以谷歌搜索"数据哈希"和"反向索引"。请注意,这也损害了安全性。
-
有理论上的结果,但我还没有找到任何接近实现的东西。
如果数据相对较小,另一种选择是将数据缓存在服务器内存中,并对缓存的数据集执行正则表达式匹配操作。在以下情况下,这可能是有意义的:
- 每所学校有 ~1000 名学生
- 您的缓存键使得给定学校只能在其学生中搜索
- 您可以缓存搜索所需的最小字段集,而无需序列化整个对象
当然,黑客有可能访问您的网络服务器内存并读取数据。这可以通过设计良好的缓存刷新策略部分缓解。