加密后的数据怎样进行含糊查询?本日面了 10 个,没一个能答上来的! ...

打印 上一主题 下一主题

主题 893|帖子 893|积分 2679

作者:凝雨-Yun
原文:https://ningyu1.github.io/20201230/encrypted-data-fuzzy-query.html
我们知道加密后的数据对含糊查询不是很友好,本篇就针对加密数据含糊查询这个问题来展开讲一讲实现的思路,希望对大家有所开导。
为了数据安全我们在开发过程中经常会对重要的数据进行加密存储,常见的有:密码、手机号、电话号码、具体地址、银行卡号、信用卡验证码等信息,这些信息对加解密的要求也不一样,比如说密码我们必要加密存储,一般使用的都是不可逆的慢hash算法,慢hash算法可以避免暴力破解(典型的用时间换安全性)。
在检索时我们既不必要解密也不必要含糊查找,直接使用密文完全匹配,但是手机号就不能如许做,由于手机号我们要查看原信息,而且对手机号还必要支持含糊查找,因此我们本日就针对可逆加解密的数据支持含糊查询来看看有哪些实现方式。
在网上随便搜刮了一下,关于《加密后的含糊查询》 的帖子许多,顺便整理了一下实现的方法,不得不说许多都是不靠谱的做法,乃至有一些沙雕做法,接下来我们就对这些做法来讲讲实现思路和优劣性。
怎样对加密后的数据进行含糊查询

我整理了一下对加密的数据含糊查询大抵分为三类做法,如下所示:

  • 沙雕做法(不动脑思索直男的思路,只管实现功能从不深入思索问题)
  • 通例做法(思索了查询性能问题,也会使用一些存储空间换性能等做法)
  • 超神做法(比较高端的做法从算法层面上思索)
我们就对这三种实现方法一一来讲讲实现思路和优劣性,起首我们先看沙雕做法。
推荐一个开源免费的 Spring Boot 实战项目:
https://github.com/javastacks/spring-boot-best-practice
沙雕做法


  • 将所有数据加载到内存中进行解密,解密后通过步伐算法来含糊匹配
  • 将密文数据映射一份明文映射表,俗称tag表,然后含糊查询tag来关联密文数据
沙雕一

我们先来看看第一个做法,将所有数据加载到内存中进行解密,这个如果数据量小的话可以使用这个方式来做,如许做既简单又实惠,如果数据量大的话那就是灾难,我们来大抵算一下。
一个英文字母(不分大小写)占一个字节的空间,一个中文汉字占两个字节的空间,用DES来举例,13800138000加密后的串HE9T75xNx6c5yLmS5l4r6Q==占24个字节。
条数BytesMB100w2400万22.891000w2.4亿228.891亿24亿2288.89轻则上百兆,重则上千兆,如许分分钟给应用步伐整成Out of memory,如许做如果数据少只有几百、几千、几万条时是完全可以如许做的,但是数据量大就强烈不建议了。
沙雕二

我们再来看第二个做法,将密文数据映射一份明文映射表,然后含糊查询映射表来关联密文数据,what???!!!那我们为什么要对数据加密呢,直接不加密不是更好么!
我们既然对数据加密肯定是有安全诉求才会如许做,增加一个明文的映射表就违背了安全诉求,如许做既不安全也不方便完全是脱裤子放x,多此一举,强且不推荐。
通例做法

我们接下来看看通例的做法,也是最广泛使用的方法,此类方法及满意的数据安全性,又对查询友好。

  • 在数据库实现加密算法函数,在含糊查询的时候使用decode(key) like '%partial%
  • 对密文数据进行分词组合,将分词组合的结果集分别进行加密,然后存储到扩展列,查询时通过key like '%partial%'
通例一

在数据库中实现与步伐一致的加解密算法,修改含糊查询条件,使用数据库加解密函数先解密再含糊查找,如许做的长处是实现成本低,开发使用成本低,只必要将以往的含糊查找轻微修改一下就可以实现,但是缺点也很显着,如许做无法利用数据库的索引来优化查询,乃至有一些数据库可能无法保证与步伐实现一致的加解密算法,但是对于通例的加解密算法都可以保证与应用步伐一致。
如果对查询性能要求不是特别高、对数据安全性要求一般,可以使用常见的加解密算法比如说AES、DES之类的也是一个不错的选择。
如果公司有自己的算法实现,而且没有提供多端的算法实现,要么找个算法好的人去研究吃透补全多端实现,要么放弃使用这个办法。
通例二

对密文数据进行分词组合,将分词组合的结果集分别进行加密,然后存储到扩展列,查询时通过key like '%partial%',这是一个比较划算的实现方法,我们先来分析一下它的实现思路。
先对字符进行固定长度的分组,将一个字段拆分为多个,比如说根据4位英文字符(半角),2个中文字符(全角)为一个检索条件,举个例子:
ningyu1使用4个字符为一组的加密方式,第一组ning ,第二组ingy ,第三组ngyu ,第四组gyu1 … 依次类推。
如果必要检索所有包罗检索条件4个字符的数据比如:ingy ,加密字符后通过 key like “%partial%” 查库。
我们都知道加密后长度会增长,增长的这部分长度存储就是我们要花费的额外成本,典型的使用成本来换取速度,密文增长的幅度随着算法不同而不同以DES举例,13800138000加密前占11个字节,加密后的串HE9T75xNx6c5yLmS5l4r6Q==占24个字节,增长是2.18倍,所以一个优秀的算法是多么的重要,能为公司节省不少成本,但是话又说回来算法工程师的工资也不低,所以我也不知道是节省成本照旧增加成本,哈哈哈…你们自己算吧。
回到主题,这个方法虽然可以实现加密数据的含糊查询,但是对含糊查询的字符长度是有要求的,以我上面举的例子含糊查询字符原文长度必须大于即是4个英文/数字,或者2个汉字,再短的长度不建议支持,由于分词组合会增多从而导致存储的成本增加,反而安全性降低。
大家是否都对接过 淘宝、拼多多、JD他们的api,他们对平台订单数据中的用户敏感数据就是加密的同时支持含糊查询,使用就是这个方法,下面我整理了几家电商平台的密文字段检索方案的说明,感爱好的可以查看下面链接。
ps. 基本上都是一样的,果然都是相互抄袭,连加密后的数据格式都一致。
这个方法长处就是实现起来不算复杂,使用起来也较为简单,算是一个折中的做法,由于会有扩展字段存储成本会有升高,但是可利用数据库索引优化查询速度,推荐使用这个方法。
超神做法

我们接下来看看优秀的做法,此类做法难度较高,都是从算法层面来考虑,有些乃至会设计一个新算法,虽然已有一些现成的算法参考,但是大多都是半成品无法拿来直接使用,所以照旧要有人去深入研究和整合到自己的应用中去。
从算法层面思索,乃至会设计一个新算法来支持含糊查找
这个层面大多是专业算法工程师的研究领域,想要设计一个有序的、非不可逆的、密文长度不能增长过快的算法不是一件简单的事情,大抵的思路是如许的,使用译码的方式进行加解密,保留密文和原文一样的顺序,从而支持密文含糊匹配,说的比较笼统由于我也不是这方面的专家没有更深一步的研究过,所以我从网上找了一些资料可以参考一下。
这里提到的Hill密码处理和含糊匹配加密方法FMES可以重点看看.
基于Lucene的思路就跟我们上面介绍的通例做法二类似,对字符进行等长度分词,将分词后的结果集加密后存储,只不过存储的db不一样,一个是关系型数据库,一个是es搜刮引擎。
总结

我们到这里对加密数据的检索方案全部介绍完了,我们起首提到的是网上搜刮随处可见的沙雕做法,在这里也讲了不推荐使用这些沙雕做法,尽量使用通例做法,如果公司有专业算法方向人才的话不妨可以考虑基于算法层面的超神做法。
总的来说从投入、产出比、及实现、使用成本来算的话通例做法二好坏常推荐的。
更多文章推荐:
1.Spring Boot 3.x 教程,太全了!
2.2,000+ 道 Java面试题及答案整理(2024最新版)
3.免费获取 IDEA 激活码的 7 种方式(2024最新版)
觉得不错,别忘了随手点赞+转发哦!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

干翻全岛蛙蛙

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表