Laravel 加密 - 比较值

7
鉴于 Laravel 的 Crypt 总是添加 salt,因此相同加密的两个实例永远不同。通常情况下,这没问题,因为可以比较两个解密后的值。但是,如果我想要在数据库中搜索一个加密的值呢?例如,我有一个名为 users 的表格,我想要加密电子邮件地址,并通过电子邮件地址 test@email.com 查找某人。如何编写此查询?我不能只使用 Crypt::encrypt($email) 并进行搜索,因为此次 encrypt 的迭代与数据库中的迭代不同。 编辑 目前,我唯一能想到的方法就是获取所有数据,然后筛选它们:
$match = User::all()->filter(function($record) use($email) {
            $field = $record->email['email'];

            if(Crypt::decrypt($field) == $email) return $record;
         });

但这太糟糕了。我不想搜索所有的内容。

3
我认为唯一的解决方法是使用固定的keyiv对数据进行加密。扩展Crypt类以实现这一点并不难。 - Jeemusu
你可以考虑添加另一列,其中包含电子邮件的哈希值,以供比较。 - Wing Lian
1个回答

2
如描述一样,您不能这样做。如果您不需要进行优化,则给出的答案是实现它的方法。
如果您需要优化它,而又不完全破坏加密值,并且已经分析了您的过滤器返回和处理的数据量是延迟的主要原因,则可以执行以下操作。
向表中添加一个新字段,该字段将存储哈希的子集。根据唯一电子邮件地址的数量,可以调整此子集的大小。注意:越小越好,因为使用此方法会泄漏一些有关加密值的信息。例如,如果您存储电子邮件地址的1字节哈希值,则会将加密的熵降低约8位。
查询时,请首先创建电子邮件哈希的子集并放置一个where子句,仅返回这些行。
所有这些都假定哈希函数比解密步骤更便宜。这种方法需要您重新计算所有哈希子集,如果您想增加其大小,则选择有意义地提高性能、不过度损害加密并可能不需要随着您的增长而改变的大小很重要。
注意:在这种情况下,您不应该使用MD5之类的直接哈希。不是因为它容易发生碰撞,而是因为密钥空间非常小。如果性能很重要,并且您存储大量数据,则会打开DOS攻击,攻击者会创建大量电子邮件地址,所有这些地址都与同一个子集哈希。为了加强对抗这个问题的能力,请使用带有秘密密钥的HMAC函数。
请记住,除非您确实出于性能原因需要添加复杂性 - 否则不要这样做。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接