如何搜索带有加密字段的 MySQL 数据库

Ste*_*eAp 17 mysql

假设我需要加密某些表的字段的MySQL数据库。此外,我需要搜索我加密的一些字段

无论如何,人们将如何搜索这些字段?

一步一步解密每条记录是没有选择的:假设我有数千条记录。解密每条记录并检查每条记录是否与搜索匹配会花费太多时间和空间。

更新 2012-09-07

向数据库架构添加更多详细信息就可以了,因为我即将实现一个新应用程序。此外,我需要扩展当前在生产中运行的应用程序。但即使对于那些应用程序,添加更多细节也可以。

更新 2012-09-08

加密是这个问题的核心。

某些答案提出的访问限制已经适用 - 但不符合加密数据的正式要求。

此正式要求不是 支付卡行业数据安全标准[PCI]。

Jer*_*acs 12

显然,它们不应该被查看,因此搜索它们将是有问题的。

我过去使用的一个技巧是在加密之前对加密数据进行散列,并将散列存储在索引列中。当然,这仅在您搜索整个值时才有效;部分值不会有相同的哈希值。

如果需要,您可以通过创建哈希的“全文”索引来扩展它,但它可能会很快变得复杂。

附录

有人建议我在我的回答中添加一个脚注,以讨论有关字典攻击漏洞的冗长辩论,因此我将讨论上述方法的这种潜在安全风险。

字典攻击:字典攻击是指有人预先对已知值列表进行散列,并将散列与数据库中的散列列进行比较。如果他们可以找到匹配项,则已知值实际上可能是被散列的值(虽然不确定,因为不能保证散列值是唯一的)。这通常可以通过附加或预先添加随机“盐”来散列值来缓解,因此散列将与字典不匹配,但上述答案不能使用盐,因为您失去了可搜索性。

这种攻击在处理诸如密码之类的事情时是危险的:如果您创建一个流行密码哈希字典,那么您可以快速搜索该哈希值的表并识别拥有此类密码的用户并有效提取凭据以窃取该用户的身份.

对于具有高基数的物品,例如 SSN、信用卡号、GUID 等,它的危险性较小(但存储这些有不同的风险 [阅读:合法],所以我不倾向于建议存储它们)。

这样做的原因是为了让字典攻击起作用,您需要预先构建一个包含可能值及其散列的字典。理论上,您可以构建一个包含所有可能的 SSN 的字典(十亿行,假设所有格式排列都被删除;信用卡的数十万亿个条目)......但这通常不是字典攻击的重点,并且基本上可以与蛮力攻击相媲美,在这种攻击中,您可以系统地调查每个值。

如果您尝试将 SSN 与某个人匹配,您还可以查找特定的SSN 或信用卡号。同样,通常不是字典攻击的重点,但可以这样做,所以如果这是你需要避免的风险,我的回答对你来说不是一个好的解决方案。

所以你有它。与所有加密数据一样,加密通常是有原因的,因此请注意您的数据以及您试图保护它的内容。


小智 5

你可能想看看CryptDB。它是 MySQL 和 PostgreSQL 的前端,允许透明存储和查询加密数据。它的工作原理是在数据在应用程序和数据库之间传递时加密和解密数据,重写查询以对加密数据进行操作。并通过动态调整每列的加密模式以仅公开应用程序使用的查询所需的信息。

CryptDB 使用的各种加密方法包括:

  • RND,一种完全 IND-CPA 安全加密方案,它不会泄露有关数据的任何信息(除了它的存在以及对于可变长度类型的长度),但只允许存储和检索,不允许查询。

  • DET,RND 的一种变体,它是确定性的,因此两个相同的值(在同一列中)加密为相同的密文。支持表单的等式查询WHERE column = 'constant'

  • OPE,一种保序加密方案,支持不等式查询,例如WHERE column > 'constant'.

  • HOM,一种部分同态加密方案 (Paillier),它允许通过将密文相乘来将加密值加在一起。支持SUM()查询、加法和递增。

  • SEARCH,一种支持表单关键字搜索的方案WHERE column LIKE '% word %'

  • JOINOPE-JOIN是 DET 和 OPE 的变体,允许将不同列中的值相互比较。分别支持相等和范围连接。

CryptDB 的真正威力在于它动态地调整每列的加密方法以适应它所看到的查询,因此较慢和/或安全性较低的方案仅用于需要它们的列。还有各种其他有用的功能,例如将加密密钥链接到用户密码。

如果您有兴趣,建议您查看从 CryptDB 网站链接的论文,特别是Popa、Redfield、Zeldovich 和 Balakrishnan ( SOSP 2011 )所著的“CryptDB: Protecting Confidentiality with Encrypted Query Processing”。这些论文还更详细地描述了支持不同查询类型所涉及的各种安全性和性能权衡。


Phi*_*lᵀᴹ 5

我不明白为什么当前的答案没有完全质疑要求,所以我会问并将其保留为答案。

商业原因是什么?您需要加密哪些数据以及为什么?如果您正在寻找 PCI 合规性,我可以写一篇文章。

关于您的要求的问题:

  • 您需要返回存在/不存在作为结果,还是实际数据?
  • 您需要类似“%OMG_SEKRIT%”的功能吗?
  • 谁看不到数据,为什么?

RDBMS 安全性通常是在由用户/角色强制执行的权限基础上完成的。数据通常由磁盘上的 RDBMS 加密,但列式数据本身不会加密,因为这对于旨在高效存储和检索数据的应用程序来说没有任何意义。

按用户/角色/api 进行限制。在磁盘上加密。如果您要存储更重要的数据,我很想知道您为什么使用 MySQL。