委屈求全下的密文字段检索

105 阅读2分钟

看了很多资料,都没有比较好的处理密文字段检索的方案。通过学习,自己想到一个委屈求全的方案


和大部分的想法一样,以手机号为密文查询为例,参考前人文章,如18200256007,按每3位为一组,进行拆分,拆分后的字符串为:182,820,200,002,025,256,560,600,007,这9组数据。根据自己业务需求,可自行按需进行分组。这里的分组和elasticsearch的分词异曲同工。

加密之后,用逗号分割之后拼接成这样的字符串
 据:,U2FsdGVkX19Se8cEpSLVGTkLw/yiNhcB,U2FsdGVkX1+qysCDyVMm/aYXMRpCEmBD,U2FsdGVkX19oXuv8m4ZAjz+AGhfXlsQk,U2FsdGVkX19VFs60R26BLFzv5nDZX40U,U2FsdGVkX19XPO0by9pVw4GKnGI3Z5Zs,U2FsdGVkX1/FIIaYpHlIlrngIYEnuwlM,U2FsdGVkX19s6WTtqngdAM9sgo5xKvld,U2FsdGVkX19PmLyjtuOpsMYKe2pmf+XW,U2FsdGVkX1+cJ/qussMgdPQq3WGdp16Q。
 
在主表冗余一个字段或者建一个关联表均可,存储拼接好的字符串。

此时要进行模糊查询,如页面检索“8200”,分组后,820,200,对当前两个分组数字进行加密后,进行模糊查询,如
select id,phone from xxx where encry_phone like '%820的加密字符串%' or encry_phone like '%200的加密字符串%';


此时返回的记录字段包含主表id和加密后的手机号,此时返回的记录已经过滤了很多数据,返回的数据也不会很多,不容易内存溢出。

将返回的所有记录的手机号进行解密,在代码里进行过滤处理,筛选出所有包含“8200”的记录id,将id集合作为查询条件,去主表进行分页查询。

分组的细粒度越高,查询的准确率越高,性能越差,如手机号,按照2位进行分组,有10组,如果按照1位进行分组,最终有11组。
查询条件按照对应的分组规则进行分组,如“8200”,按2位分组,则为82,20,00,查询时需要三个模糊查询,如果按1位分组,则为8,2,0,0,查询时需要组装4个模糊查询条件,查询性能越差,返回满足条件的筛选记录也越多。


参考资料:https://juejin.cn/post/7288963208408563773