加密数据库字段的用户查找

3
基本上,我有一个包含用户数据的表格,其中所有数据都是以AES加密方式存储的(在BLOB字段中)。
这意味着那些字段都不能被索引,这将会使得该表上的任何查询速度变慢 - 特别是因为在进行匹配前,整个表格都需要被解密...
... WHERE AES_DECRYPT(`user`.`email`, '{$sSomeKeyHere}') = '{$sSubmittedEmail}'

因此,我的要求是有一个只包含哈希值且未加密的字段,可用于快速查找的索引。最佳查找可能是电子邮件地址(小写、反转和哈希或其他可复制的过程的一些派生物),以便您可以有效地搜索电子邮件地址而无需解密电子邮件地址...但我需要保证其安全。

因此,我正在考虑以下选项:

1:将电子邮件地址转换为小写并进行SHA-256(或512)哈希,然后再将其插入数据库中

2:稍微复杂一点;在对电子邮件地址进行哈希之前,使用其他可复制的函数对其进行混淆处理。

3:从user.last_login_date(未加密)创建盐字符串,并使用它对电子邮件地址创建腌制哈希 - 并在每次用户登录时更新查找字段(因为盐会改变)。然而,这需要一个稍微复杂一些的SELECT语句,仅限于MySQL引擎内置的任何散列函数,因为我需要使用上次登录日期重新创建哈希来执行搜索。


所以问题是,只选择选项1可以吗?

选项2更好吗?

选项3是否像我认为的那样过度极端?

或者我是否忽略了完全明显的事实,事实上有一个更好的解决方案?

2个回答

2
为什么不使用反向的呢?
... WHERE `user`.`email` = AES_ENCRYPT('{$sSubmittedEmail}'`, '{$sSomeKeyHere}')

加密字符串可以通过base64或类似函数存储到VARCHAR类型中。


眨眼 ...那么选项4吧 :) 我错过了一些显而易见的东西!我喜欢这种优雅,但我认为MySQL(基于MyISAM,原因最好不提)只允许您将AES加密字符串插入到BLOB字段以外的任何地方?更正 - 刚刚检查,它也适用于TEXT字段...但是再次强调,除了FULLTEXT之外,它无法被索引。 - CD001
如果您使用的是MySQL 5.6或更高版本,只需使用TO_BASE64将加密的二进制转换为字符串即可。如果不是,则在应用程序级别进行加密和解密,或添加Base64 UDF。请参见https://dev59.com/1nRC5IYBdhLWcg3wROpQ。 - lqez
很不幸,这是MySQL 5.1版本(Slackware在构建方面相当保守) - 并且应用程序级别的base64编码可以将0x0包含到字符串中 - 这是VARCHAR字段中的终止符 - 所以再次强调,它只能与BLOB或TEXT一起使用?在看到您的帖子后,我研究过它,以查看是否能够使其工作;本质上,它正在应用程序中重新创建AES_ENCRYPT,并将Base64编码的字符串转换为VARCHAR...但实际上我并没有太多成功的运气 :\ - CD001
base64 可以将任何二进制数据编码成字符串。http://en.wikipedia.org/wiki/Base64 因此,您可以将其存储到“普通”字符类型列中,并且还可以为其创建索引。相信我。 - lqez
谢谢 - 我明天会坚持一下 :) - CD001

0

选项1。

您的数据可以进行索引以进行搜索和比较,但只能针对加密的搜索项。


我想我会选择选项1 - 因为整个重点是基于电子邮件地址(来自用户输入)创建一个安全可索引字段,而根据我的了解,在MySQL中使用VARCHAR(或类似)的哈希是实现这一目标的唯一方法。这不是一个真正复杂的搜索,只是一个快速的标识符,可以放入SELECTWHERE中,以检索用于验证或其他用途的数据。这使我可以在电子邮件地址上进行索引搜索,从而获得快速查询,并且只需要解密单个行而不是整个表 :) - CD001

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