关于java:美团二面加密后的数据如何进行模糊查询被问懵了

8次阅读

共计 3635 个字符,预计需要花费 10 分钟才能阅读完成。

咱们晓得加密后的数据对含糊查问不是很敌对,本篇就针对加密数据含糊查问这个问题来开展讲一讲实现的思路,心愿对大家有所启发。

为了数据安全咱们在开发过程中常常会对重要的数据进行加密存储,常见的有:明码、手机号、电话号码、具体地址、银行卡号、信用卡验证码等信息,这些信息对加解密的要求也不一样,比如说明码咱们须要加密存储,个别应用的都是不可逆的慢 hash 算法,慢 hash 算法能够防止暴力破解(典型的用工夫换安全性)。

在检索时咱们既不须要解密也不须要含糊查找,间接应用密文齐全匹配,然而手机号就不能这样做,因为手机号咱们要查看原信息,并且对手机号还须要反对含糊查找,因而咱们明天就针对可逆加解密的数据反对含糊查问来看看有哪些实现形式。

在网上轻易搜寻了一下,对于《加密后的含糊查问》的帖子很多,顺便整顿了一下实现的办法,不得不说很多都是不靠谱的做法,甚至有一些沙雕做法,接下来咱们就对这些做法来讲讲实现思路和优劣性。

如何对加密后的数据进行含糊查问

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

  • 沙雕做法(不动脑思考直男的思路,只管实现性能从不深刻思考问题)
  • 惯例做法(思考了查问性能问题,也会应用一些存储空间换性能等做法)
  • 超神做法(比拟高端的做法从算法层面上思考)

咱们就对这三种实现办法一一来讲讲实现思路和优劣性,首先咱们先看沙雕做法。

沙雕做法

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

沙雕一

咱们先来看看第一个做法,将所有数据加载到内存中进行解密,这个如果数据量小的话能够应用这个形式来做,这样做既简略又实惠,如果数据量大的话那就是劫难,咱们来大抵算一下。

一个英文字母 (不分大小写) 占一个字节的空间,一个中文汉字占两个字节的空间,用 DES 来举例,13800138000加密后的串 HE9T75xNx6c5yLmS5l4r6Q==24个字节。

条数 Bytes MB
100w 2400 万 22.89
1000w 2.4 亿 228.89
1 亿 24 亿 2288.89

轻则上百兆,重则上千兆,这样分分钟给应用程序整成Out of memory,这样做如果数据少只有几百、几千、几万条时是齐全能够这样做的,然而数据量大就强烈不倡议了。

举荐一个 Spring Boot 根底实战教程:

https://github.com/javastacks…

沙雕二

咱们再来看第二个做法,将密文数据映射一份明文映射表,而后含糊查问映射表来关联密文数据,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,他们对平台订单数据中的用户敏感数据就是加密的同时反对含糊查问,应用就是这个办法,上面我整顿了几家电商平台的密文字段检索计划的阐明,感兴趣的能够查看上面链接。

  • 淘宝密文字段检索计划:https://open.taobao.com/docV3…
  • 阿里巴巴文字段检索计划:https://jaq-doc.alibaba.com/d…
  • 拼多多密文字段检索计划:https://open.pinduoduo.com/ap…
  • 京东密文字段检索计划:https://jos.jd.com/commondoc?…

ps. 基本上都是一样的,果然都是相互剽窃,连加密后的数据格式都统一。

这个办法长处就是实现起来不算简单,应用起来也较为简单,算是一个折中的做法,因为会有扩大字段存储老本会有升高,然而可利用数据库索引优化查问速度,举荐应用这个办法。

超神做法

咱们接下来看看优良的做法,此类做法难度较高,都是从算法层面来思考,有些甚至会设计一个新算法,尽管已有一些现成的算法参考,然而大多都是半成品无奈拿来间接应用,所以还是要有人去深入研究和整合到本人的利用中去。

从算法层面思考,甚至会设计一个新算法来反对含糊查找

这个层面大多是业余算法工程师的钻研畛域,想要设计一个有序的、非不可逆的、密文长度不能增长过快的算法不是一件简略的事件,大抵的思路是这样的,应用译码的形式进行加解密,保留密文和原文一样的程序,从而反对密文含糊匹配,说的比拟抽象因为我也不是这方面的专家没有更深一步的钻研过,所以我从网上找了一些材料能够参考一下。

  • 数据库中字符数据的含糊匹配加密办法:https://www.jiamisoft.com/blo…

这里提到的 Hill 明码解决和含糊匹配加密办法 FMES 能够重点看看.

  • 一种基于 BloomFilter 的改进型加密文本含糊搜寻机制钻研:http://kzyjc.cnjournals.com/h…
  • 反对疾速查问的数据库如何加密:https://www.jiamisoft.com/blo…
  • 基于 Lucene 的云端搜寻与密文根底上的含糊查问:https://www.cnblogs.com/arthu…

基于 Lucene 的思路就跟咱们下面介绍的惯例做法二相似,对字符进行等长度分词,将分词后的后果集加密后存储,只不过存储的 db 不一样,一个是关系型数据库,一个是 es 搜索引擎。

  • 云存储中一种反对可验证的含糊查问加密计划:http://jeit.ie.ac.cn/fileDZYX…

总结

咱们到这里对加密数据的检索计划全副介绍完了,咱们首先提到的是网上搜寻随处可见的沙雕做法,在这里也讲了不举荐应用这些沙雕做法,尽量应用惯例做法,如果公司有业余算法方向人才的话无妨能够思考基于算法层面的超神做法。

总的来说从投入、产出比、及实现、应用老本来算的话惯例做法二是十分举荐的。

起源:ningyu1.github.io/20201230/encrypted-data-fuzzy-query.html

近期热文举荐:

1.1,000+ 道 Java 面试题及答案整顿(2022 最新版)

2. 劲爆!Java 协程要来了。。。

3.Spring Boot 2.x 教程,太全了!

4. 别再写满屏的爆爆爆炸类了,试试装璜器模式,这才是优雅的形式!!

5.《Java 开发手册(嵩山版)》最新公布,速速下载!

感觉不错,别忘了顺手点赞 + 转发哦!

正文完
 0