使用PHP与SQL搭建可搜索的加密数据库
作者:莎莎 发布时间:[ 2017/6/1 10:42:56 ] 推荐标签:SQL 数据库
安全分析与限制
根据你的确切威胁模型,这个解决方案留下了两个必须回答的问题:
是否真的可以安全使用,还是说可能仍然会泄漏数据,像滤网一样?
它的用途有什么局限性?(这一个其实已经回答了。)
以上我们的例子中,假设您的加密密钥和盲索引键是分开的,两个密钥都存储在Web服务器中,而数据库服务器没有任何方法来获取这些密钥,那么任何攻击者只会破坏数据库服务器但不是Web服务器)只能够了解若干行是否共享一个社会安全号码,而不是共享SSN是什么。为了使索引成为可能,这种重复的条目泄漏是必要的,这又允许从用户提供的值进行快速的SELECT查询。
此外,如果攻击者能够在遵守存储在数据库中的盲目索引的同时观察/更改明文作为应用程序的普通用户,则可以将其利用为选择的明文攻击,在这些攻击中,它们以用户身份迭代每个可能的值然后与所得的盲目索引值相关联。这在HMAC方案中比在Argon2方案中更实际。而对于高熵或低灵敏度值(而不是SSN)来说,我只能说物理学真的在我们身边。
对于现在这样的情况,犯罪分子要想进行更实际的攻击要将值从一行替换到另一行,然后正常访问应用程序,而这将会揭示明文,除非采用了独特的每行密钥(例如hash_hmac('sha256', $rowID, $masterKey, true)甚至可以在这里有效缓解)其他人会更喜欢)。这里好的防御是使用AEAD模式(将主键作为附加关联数据传递),以便将密文连接到特定的数据库行。(这样做并不会阻止攻击者删除数据,这是一个更大的挑战。)
与其他解决方案泄露的信息量相比,大多数应用程序的威胁模型应该将其视为可接受的权衡。只要您使用身份验证加密进行加密,以及HMAC(用于盲目索引非敏感数据)或密码散列算法(盲目索引敏感数据),很容易理解应用程序的安全性。
然而,它确实有一个非常严重的限制:它只适用于完全匹配。如果两个字符串以无意义的方式不同,但总是会产生不同的加密散列,则搜索一个不会产生另一个。如果您需要执行更多高级查询,但是仍然希望将解密密钥和明文值保留在数据库服务器的手中,我们将必须获得创造性。
还值得注意的是,虽然HMAC / Argon2可以防止不具有密钥的攻击者学习数据库中存储的明文值,但它可能在现实世界会显示元数据(例如两个看似无关的人共享一个街道地址)。
实现加密数据的模糊搜索
可能的用途:加密人们的法定名称,并能够仅搜索部分匹配内容。
我们在上一节的基础上构建一个盲目索引,让您可以查询数据库的精确匹配。
这一次,我们将不会在现有表中添加列,而是将额外的索引值存储到连接表中。
CREATE TABLE humans (
humanid BIGSERIAL PRIMARY KEY,
first_name TEXT, /* encrypted */
last_name TEXT, /* encrypted */
ssn TEXT, /* encrypted */
);
CREATE TABLE humans_filters (
filterid BIGSERIAL PRIMARY KEY,
humanid BIGINT REFERENCES humans (humanid),
filter_label TEXT,
filter_value TEXT
);
/* Creates an index on the pair. If your SQL expert overrules this, feel free to omit it. */
CREATE INDEX ON humans_filters (filter_label, filter_value);
这种变化的原因是规范化我们的数据结构。你可以通过添加列到现有的表,但它可能会变得混乱。
接下来的改变是,我们将为每个不同类型的查询(每个都有自己的密钥)为每列存储一个单独的,不同的盲目索引。例如:
需要忽略空格的不区分大小写的查找?
存储盲目索引preg_replace('/[^a-z]/', '', strtolower($value))。
需要查询他们姓氏的第一个字母?
存储盲目索引strtolower(mb_substr($lastName, 0, 1, $locale))。
需要匹配“这个字母,并在那个字母结束”?
存储盲目索引strtolower($string[0] . $string[-1])。
需要查询他们姓氏的前三个字母和他们的名字的第一个字母?
你猜对了!基于部分数据来构建另一个索引。
每个指标都需要有一个独特的关键,应该大力刺激明文隐含的盲目索引,将真正的明文值泄露给一个犯罪分子,用谜语填字游戏。只能为严重的业务需求创建索引,并且积极地记录对应用程序这些部分的访问。
时间与存储的交易
到目前为止,所有设计命题都赞成允许开发人员仔细阅读SELECT查询,同时小化解密子例程的次数。一般来说,这样已经能做到让大多数人满意了。
但是,有些情况下,如果意味着节省大量的磁盘空间,搜索查询中的轻微性能也可以接受。
这里的技巧很简单:将您的盲目索引截断为16,32或64位,并将其视为 Bloom过滤器:
如果查询中涉及到的盲目索引与给定行匹配,则数据可能是一个匹配项。
您的应用程序代码将需要为每个候选行执行解密,然后仅提供实际匹配。
如果查询中涉及的盲指数与给定行不匹配,则数据不匹配。
如果您的数据库服务器终会更有效地存储它,也可能会将这些值从字符串转换为整数。
本文内容不用于商业目的,如涉及知识产权问题,请权利人联系SPASVO小编(021-61079698-8054),我们将立即处理,马上删除。
相关推荐
在测试数据库性能时,需要注意哪些方面的内容?测试管理工具TC数据库报错的原因有哪些?怎么解决?数据库的三大范式以及五大约束编程常用的几种时间戳转换(java .net 数据库)优化mysql数据库的几个步骤数据库并行读取和写入之Python实现深入理解数据库(DB2)缓冲池(BufferPool)国内三大云数据库测试对比预警即预防:6大常见数据库安全漏洞数据库规划、设计与管理数据库-事务的概念SQL Server修改数据库物理文件存在位置用Python写一个NoSQL数据库详述 SQL 中的数据库操作详述 SQL 中的数据库操作Java面试准备:数据库MySQL性能优化oracle数据库碎片化管理
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11热门文章
常见的移动App Bug??崩溃的测试用例设计如何用Jmeter做压力测试QC使用说明APP压力测试入门教程移动app测试中的主要问题jenkins+testng+ant+webdriver持续集成测试使用JMeter进行HTTP负载测试Selenium 2.0 WebDriver 使用指南