已编辑:请参阅最后的重要说明,这是在我最初发布然后重新阅读问题后添加的。
我唯一能想到的就是使用哈希构建索引表。但是,这无疑会削弱您的安全性,因为我们正在交换完全加密,(希望)不会泄露有关哈希表内容的任何信息,这会泄露有关用户数据内容的信息(知道索引的术语数量)给定的帐户为攻击提供了频率分析的立足点)。
注意:我做出以下假设:每个用户都有不同的 iv。
在对数据库行进行加密之前,您可以读取这些行并将它们标记为将索引这些项目的表。然后,您将使用从 iv 生成的盐对令牌进行哈希处理。所以,现在,对于给定的用户,“secretfoo”在索引中保存为c9a60f248c3a99e2b7004061d5c74e5f2240426f1f0f95eaf5843aa875e68542
.
搜索时,您需要遍历所有 ivs 以生成所有盐,然后执行对令牌的搜索c9a60f248c3a99e2b7004061d5c74e5f2240426f1f0f95eaf5843aa875e68542
以找到包含“secretfoo”的记录。
这将是一个更快的搜索,但这里需要以速度换取安全性。因为您实际上已经为给定单词保存了一个哈希字典,所以如果要泄露数据库,则有可能(但不太可能)索引信息可用于组装原始数据。至少,它可以用来组装关于数据的元数据。话虽如此,计算起来会很困难。
让我们假设您有 100,000 个用户,每个用户大约 100 行,总表大小为 100,000,000 行数据。
解密所有 100,000,000 百万以执行非索引搜索将花费大量时间。
在上述范例下,您只需要生成 100,000 个散列并在索引中搜索每个散列一次即可找到所需的记录。此外,我们可以匹配整个字符串(散列)而不必执行任何子字符串搜索。
这具有计算 100,000 个哈希值并在 BTREE 索引表上执行 100,000 次搜索的优势,从而为我们提供了良好的结果。
正如 Mike Ounsworth 所指出的,您仍然必须决定哪些是敏感数据,哪些不是敏感数据才能进行搜索;但是,对所有令牌进行 SHA256 哈希处理比明文好几个数量级。
编辑:
发表我的帖子后,我重新阅读了您的问题,并意识到您已将 iv 保存在数据库中,这会使索引容易被泄露。
解决这个问题的唯一方法是将 iv 存储在一个单独的数据库中,该数据库不暴露给网络,并且只能通过 API 访问。这是 PCI 兼容应用程序中的常见设置。
进行查询时,您的面向 Web 的应用程序必须向安全服务器询问要从中生成哈希的 iv,并执行搜索。
这是一个更复杂的实现,但如果 iv 在面向 Web 的数据库中,并且它被泄露了,那么他们所要做的就是遍历 ivs 以解密整个索引。