密文字段模糊检索方案

代码地址: https://github.com/zuiyu-main/EncryptDemo

https://mp.weixin.qq.com/s/cXOg1tiMtJz2eibDZmXHUQ

在个别特殊领域中,数据的安全问题是非常的重要的,所以需要数据库存储的数据是需要加密存储的。所以也就引申出来本文这个问题,加密之后的密文,还能模糊检索吗,如果能检查,如何做模糊检索呢?

现在的系统设计中,常见的加密字段有、密码、身份证号、手机号、住址信息、银行卡、信用卡以及个别行业的敏感信息。这些信息对加密的要求也不一样,对于密码来说,一般使用不可逆的加密算法就可以,一般不会用到检索。但是对于身份证号或者个别领域中的中文信息,我们是需要支持密文模糊匹配的,下面我们就来看看有哪些实现方式。

本来主要讲两种常规的简单加密做法,主要目标为能实现密文的模糊查询。下面来跟我看第一种。

常规分词加密

常规加密的密文检索功能根据4位英文字符(半角)2个中文字符(全角)作为一个检索条件,将一个字段拆分为多个字段。

比如:zuiyu123

使用4个字符为一组的加密方式。

第一组 zuiy,第二组uiyu,第三组iyu1,第四组yu12,第五组u123…如果字符串很长,依次类推下去。

如果需要检索所有包含检索条件 uiyu 的数据,加密字符后通过 key like ‘%加密uiyu的密文%’查询。

所以这种实现方式就会有一种问题就是,随着加密字符串的增加,密文也会变的越大,所以一般用此处方式需要注意数据库中的字段长度限制

需要注意的是,使用此处方式有一定的限制:

1、支持模糊检索加密,但是加密的密文随原文长度增长

2、支持的模糊检索条件必须大于等于4个英文数字或者2个汉字,不支持短的查询(自定义该局限性,业界常用的就是4个英文数字或者2个汉字,再短的长度不建议支持,因为分词组合会增多从而导致存储的成本增加,反而安全性降低。)。

3、返回的列表不是很精确,需要二次筛选,先解密在进一步筛选。

字符串拆分的代码如下:

protected List<String> loopEncryptString(String input, int chunkSize) {
        int length = input.length();
        List<String> strList = new LinkedList<>();
        for (int i = 0; i < length; i++) {
            StringBuilder chunkBuilder = new StringBuilder();
            for (int j = 0; j < chunkSize; j++) {
                int index = (i + j) % length;
                chunkBuilder.append(input.charAt(index));
            }
            strList.add(chunkBuilder.toString());

            log.info("第 {} 组:[{}]",i+1,chunkBuilder);
            // 如果到了最后一个分组,则不再循环第一个字符
            if (i + chunkSize >= length) {
                break;
            }
        }
        log.info("分词结果:[{}]",strList);
        return strList;
    }

对于上述文本zuiyu123分词效果如下

下面来看下中文的分词效果:

检索一下,只要我们使用的是包含上述分词结果的条件我们就可以检索的到。

比如我们检索个蛋白质

search result:[[{ID=8dac4d97-f05f-472e-94b2-02828aa235d6, CONTENT=ELYJBkZbfiVaJgTdlgglDg==UYwxxmEMQ9hq1jOax+r5rg==WwCBtglEf6clcWajP9sK+A==4sEGCqZ4P8Osr0dW84zFEA==c2AZejHeUp/5gpPkexfNcg==pvh/TcZRO4zwD+kwbE9lHw==1g30dxyz7z+8TQq+8jYH1A==AsWZOeiprypfrzSK3FtOuw==01vpoSuCXOpKCgcPsNlXyQ==79BPmIhSwMaA7hjN3ENDxA==}]]

可以看到,上述的content字段的内容长度非常的长,所以我们要注意数据库字段长度限制。

除了上面这个方式外,发散一下思维,如果你用过 Elasticsearch 的话,会不会有点想法呢?

因为在中文的场景中,中文既然要分词,选择专业的分词器应该是更合理的啊,所以我们可以使用???

对的,你没猜错,既然是要分词,对于特殊的中文业务场景,直接使用 Elasticsearch 的分词器分词不就好了吗,然后再用 Elasticsearch 的强大检索能力,不就可以满足我们的模糊检索需求了吗,想到就去做,下面就跟着我一起来看下如果用 Elasticsearch 的分词实现密文模糊检索。

分词器分词检索

使用分词器分词进行密文检索的原理:

1、使用 Elasticsearch 自带的正则分词器对加密后的密文进行分词。

2、检索时使用 Elasticsearch 的match进行检索。

本文演示使用AES进行加解密,所以分词器我就直接使用正则匹配,将密文中的内容按照==进行拆分。

下面我们一起进入代码时间,跟随着我的脚本来看看分词密文检索是什么样的。

也欢迎你来实操体验一下,有什么问题欢迎评论区留言告诉我,也可以关注《醉鱼Java》,私信我。

  • 创建一个使用pattern分词器的索引encrypt

    如下创建索引语句为 Elasticsearch 6.8 的语句,如果使用 7+、8+ 的需要修改为对应的版本。

    mappings 中的 _doc

    put 127.0.0.1:9200/encrypt
    {
        "settings": {
            "analysis": {
                "analyzer": {
                    "my_analyzer": {
                        "tokenizer": "my_tokenizer"
                    }
                },
                "tokenizer": {
                    "my_tokenizer": {
                        "type": "pattern",
                        "pattern": "=="
                    }
                }
            }
        },
        "mappings": {
            "_doc": {
                "properties": {
                    "content": {
                        "type": "text"
                    }
                }
            }
        }
    }
    
  • 随便对于一个密文进行分词,可以看到,已经按照我们的语气进行==拆分为多个词语了

其实不难发现,我们使用 AES 加密,就是对分词之后的每个词语进行加密,然后组成一个新的字符串。

还是上面那句话鱼肉的蛋白质含量真的高,我们看一下分词结果。

所以我们按照==拆分之后,检索式再通过加密之后的密文进行检索,也就相当于分词检索了。

检索结果如下:

search result:[{"hits":[{"_index":"encrypt","_type":"_doc","_source":{"content":"ELYJBkZbfiVaJgTdlgglDg==9hF4g5NErtZNS9qFJGYeZA==uH9W7jvdoLIKq5gOpFjhWg==4sEGCqZ4P8Osr0dW84zFEA==c2AZejHeUp/5gpPkexfNcg==1g30dxyz7z+8TQq+8jYH1A==01vpoSuCXOpKCgcPsNlXyQ==kIzJL/y/pnUbkZGjIkz4tw=="},"_id":"1713343285459","_score":2.8951092}],"total":1,"max_score":2.8951092}]

总结

密文的模糊查询就是以空间成本换取的。相比于存储原文,密文比原文增长了好几倍。

所以根据你的业务场景,选择一个合适的加密算法才是最优解。

参考

https://open.taobao.com/docV3.htm?docId=106213&docType=1

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

如果这篇文章对您有所帮助,或者有所启发的话,帮忙点个关注一下,您的支持是我坚持写作最大的动力。

求一键三连:点赞、转发、在看。

wx 搜索《醉鱼Java》,回复面试、获取2024面试资料

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/557460.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

顺丰同城急送API对接(附源码)

一、背景 最近公司让我对接顺丰同城急送的API&#xff0c;讲讲里面需要注意的几点 官方的API文档有些示例代码也不全&#xff0c;具体细节不多说&#xff0c;如果你现在也需要对接他们API&#xff0c;可以参考本篇博客再配合官方文档结合起来看&#xff0c;可以让您再开发的时…

深度学习--CNN应用--VGG16网络和ResNet18网络

前言 我们在学习这两个网络时&#xff0c;应先了解CNN网络的相关知识 深度学习--CNN卷积神经网络&#xff08;附图&#xff09;-CSDN博客 这篇博客能够帮我们更好的理解VGG16和RetNet18 1.VGG16 1.1 VGG简介 VGG论文网址&#xff1a;VGG论文 大家有兴趣的可以去研读一下…

C++设计模式|创建型 4.建造者模式

1.什么是建造者模式? 建造者模式&#xff08;也被成为生成器模式&#xff09;&#xff0c;是一种创建型设计模式&#xff0c;软件开发过程中有的时候需要创建很复杂的对象&#xff0c;而建造者模式的主要思想是将对象的构建过程分为多个步骤&#xff0c;并为每个步骤定义一个…

共享WiFi贴推广有哪些好处?一文说清

随着科技发展&#xff0c;更加智能高效便捷的共享wifi贴开始越来越多的取代了传统的wifi连接方法。 因为传统的连接WiFi方式确实存在一些不便之处。客人需要手动搜索店铺的WiFi&#xff0c;然后输入复杂的密码进行连接。这一过程不仅繁琐&#xff0c;而且容易出错。有时&#…

稳了!麒麟信安云应用助力国产化生态平稳过渡

2016年国家提出了安全可控体系并大力推进基础硬件、基础软件及应用软件的国产化建设进程。各行业及企事业单位加大国产设备及软硬件的采购力度&#xff0c;逐步完成国产化转型。而操作系统作为上层应用的载体&#xff0c;在信息建设国产化中有着举足轻重的地位。 过去几十年&a…

虚函数求圆形、矩形面积

目录 题目 源码 结果示例 题目 写一个程序&#xff0c;定义抽象基类Shape&#xff0c;由它派生出2个派生类&#xff1a;Circle(圆形)、Rectangle(矩形)&#xff0c;用一个普通函数printarea分别输出以上二者的面积&#xff0c;2个图形的数据在定义对象时给定。 源码 #inc…

软考-系统集成项目管理中级--项目质量管理(输入输出很重要!!!本章占分较高,着重复习)

本章历年考题分值统计 本章重点常考知识点汇总清单 5、成本效益分析法:对每个质量活动进行成本效益分析&#xff0c;就是要比较其可能的成本与预期的效益。达到质量要求的主要效益包括减少返工、提高生产率、降低成本、提升干系人满意度及提升赢利能力。(掌握)17下64考题 本章…

【Flutter】GetX状态管理及路由管理用法

目录 一、安装二、使用1.安装GetX插件&#xff0c;快捷生成模版代码2.主入口MaterialApp改成GetMaterialApp3.定义路由常量RoutePath类、别名映射页面RoutePages类4. 初始initialRoute&#xff0c;getPages。5.调用 总结 一、安装 dependencies: get: ^4.6.6二、使用 1.安装G…

Java八股文4

Linux篇 1.free命令-查看内存状态 free命令用于显示内存状态&#xff0c;它可以提供关于系统内存使用情况的详细信息。这个命令会显示出内存的使用情况&#xff0c;包括实体内存、虚拟的交换文件内存、共享内存区段&#xff0c;以及系统核心使用的缓冲区等。 其中&#xff0c;参…

2024年国内USB Type-C厂商的机遇与挑战分析

USB Type-C接口作为一种全新的连接标准&#xff0c;已经在各种电子设备中得到了广泛的应用。2024年&#xff0c;国内USB Type-C厂商将面临着诸多机遇和挑战&#xff0c;需要全面分析和应对&#xff0c;以确保在竞争激烈的市场中保持竞争力和持续增长。 USB TYPE-C厂商在2024年…

09-ARM开发板的HelloWorld

在ARM开发板上运行x86_64平台程序 前面在Ubuntu系统编译生成了X86_64平台的HelloWorld程序&#xff0c;通过NFS服务器&#xff0c;尝试在开发板上直接运行。 如图所示&#xff0c;程序无法正常运行&#xff0c;终端提示ARM开发板在执行x86架构&#xff08;Intel或AMD&#xff…

【Linux】地址空间虚拟地址

个人主页 &#xff1a; zxctscl 如有转载请先通知 文章目录 1. 虚拟地址1.1 虚拟地址引入1.2 虚拟地址理解1.3 虚拟地址细节问题 2. 地址空间2.1 理解地址空间2.2 页表和写时拷贝 3. 进程调度 1. 虚拟地址 1.1 虚拟地址引入 先先来一个测试代码&#xff1a; 1 #include<st…

Grass注册不了、按钮灰色的解决方案

近期相信grass挂机项目不少人有所有接触。还有不了解这个项目的可以看看博客&#xff1a; http://t.csdnimg.cn/bI4UO 但是不少人注册时遇到无法注册的问题&#xff0c;或者是注册按钮显示灰色&#xff0c;放上鼠标时显示禁止。这也是博主在尝试时遇到的问题。 经过探索&…

如何解决python安装mysqlclient失败问题

在使用Django等框架来操作MySQL时&#xff0c;实际上底层还是通过Python来操作的&#xff0c;首先需要安装一个驱动程序&#xff0c;在Python3中&#xff0c;驱动程序有多种选择&#xff0c;比如有pymysql以及mysqlclient等。使用pip命令安装mysqlclient失败应如何解决&#xf…

【Linux实践室】Linux高级用户管理实战指南:Linux用户与用户组编辑操作详解

&#x1f308;个人主页&#xff1a;聆风吟_ &#x1f525;系列专栏&#xff1a;Linux实践室、网络奇遇记 &#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 文章目录 一. ⛳️任务描述二. ⛳️相关知识2.1 &#x1f514;Linux查看用户属性命令2.1.1 &#x1f47b;…

测试用例的编写评审

1、什么叫软件测试用例 什么是测试用例 测试用例(TestCase) 是为项目需求而编制的一组测试输入、执行条件 以及预期结果&#xff0c;以便测试某个程序是否满足客户需求。–测试依据 可以总结为:每一个测试点的数据设计和步骤设计。–测试用例 2、测试用例的重要性(了解) 2.1…

社媒矩阵运营解决方案:海外云手机

在全球化的浪潮下&#xff0c;企业愈发认识到通过海外社交媒体平台扩大影响力、树立品牌形象及抢占国际市场的巨大机遇。因此&#xff0c;运营海外社交媒体账户已逐渐成为企业战略部署的重要组成部分。为了全面捕捉多渠道的流量&#xff0c;众多企业选择同时运营多个平台的多个…

基于Spring Boot的校园招聘系统

文章目录 项目介绍主要功能截图&#xff1a;部分代码展示设计总结项目获取方式 &#x1f345; 作者主页&#xff1a;超级无敌暴龙战士塔塔开 &#x1f345; 简介&#xff1a;Java领域优质创作者&#x1f3c6;、 简历模板、学习资料、面试题库【关注我&#xff0c;都给你】 &…

基于SkyEye运行Qt:著名应用程序开发框架

Qt是一个著名的跨平台的C图形用户界面应用程序开发框架&#xff0c;目前包括Qt Creator、Qt Designer等等快速开发工具&#xff0c;还支持2D/3D图形渲染、OpenGL&#xff0c;允许真正的组件编程&#xff0c;是与GTK、MFC、OWL、ATL一样的图形界面库。使用Qt开发的软件可以做到一…

抖音直播间没流量怎么办?如何快速提升直播间人气?

抖音直播间人气低迷&#xff0c;是否因为投入的资金不足或是数据表现不够抢眼而让你感到困惑&#xff1f;要提升抖音直播间的人气&#xff0c;首先需要深入了解抖音的推荐逻辑&#xff0c;探究直播间人气的真正来源。 抖音直播间的人气来源有哪些&#xff1f; 抖音直播间人气…