最新实战案例锦集:《Spring Boot 3实战案例合集》现已囊括超过50篇精选实战文章,并且此合集承诺将永久持续更新,为您带来最前沿的技术资讯与实践经验。欢迎积极订阅,享受不断升级的知识盛宴!订阅用户将特别获赠合集内所有文章的最终版MD文档(详尽学习笔记),以及完整的项目源码,助您在学习道路上畅通无阻。
环境:SpringBoot3.2.5
1. 简介
在生产环境中,数据库字段加密保存是一项至关重要的安全措施。这一措施的背景主要源于对数据安全性的高度关注,特别是在存储敏感信息时,如用户密码、个人信息、交易数据等。为了防止这些数据在数据库泄露时被曝光,需要对这些字段进行加密处理。
加密保存的原理是在数据写入数据库之前,使用加密算法对数据进行处理,使其以密文的形式存储。这样,即使数据库被非法访问,攻击者也难以获取真实的数据内容。
在生产环境中,通常都是使用对称加密算法进行处理数据,如常见的AES,SM4等算法,国密现在应该是首选,毕竟相关部门有要求。
然而,也带来了一些挑战。其中,一个常见的问题是如何在加密后的数据上进行模糊查询。传统的模糊查询依赖于数据的明文形式,而加密后的数据无法直接进行这样的操作,如下示例:
String data = "13579995139" ;String result = this.sc.encrypt(data) ;System.err.println(data + ", 加密后: " + result) ;data = "5799" ;result = this.sc.encrypt(data) ;System.err.println(data + ", 加密后: " + result) ;
这里我们对电话号码进行原文及要进行模糊查询的部分进行加密,输出结果如下:
13579995139, 加密后: dDfdATgHbaqDhkp1jIVK1A==5799, 加密后: HiO4uTs+MHjE00XcyZUilw==
根据这结果,你如果想当然的将模糊查询部分也进行加密后再模糊查询肯定是不行的,这完全不同没有规律的。
关于网络上介绍加密后的模糊查询解决方案非常的多,有全部读取到内存中解密后在内存中匹配的,有分段加密再拼接一个大字符串等方式,本篇文章将介绍另外一种方式来解决加密后模糊查询的问题。
解决方案
我们将要加密的字段值的每一个字符,通过一种算法映射为其它字符,比如:"中国",通过这种算法将其映射为:"婝估",最后将映射的字段保存到另外一个字段上,也就是说每一个需要加密的字段我们都要再对应的建立一个字段用来保存由这种算法生成的字符串。最后,我们在做查询的时候使用该映射的字段进行模糊查询(模糊的数据也进行该算法运算)。数据库保存数据如下结果:

id_no、phone字段都进行了加密,同时分别根据他们的明文数据生成映射字段key_like_id_no、key_like_phone。
接下来,我们将详细的介绍该方案的实现步骤,并且会分别使用MyBatis和JPA来实现。
2. 实战案例
2.1 准备环境及数据
<properties><bc.version>1.71</bc.version></properties><dependency><groupId>org.bouncycastle</groupId><artifactId>bcprov-jdk15to18</artifactId><version>${bc.version}</version></dependency><dependency><groupId>org.bouncycastle</groupId><artifactId>bcprov-ext-jdk15to18</artifactId><version>${bc.version}</version></dependency><dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>33.3.1-jre</version></dependency>
加密算法采用了国密SM4,所以我们引入了bouncycastle开源工具。引入guava是因为在做映射算法时需要使用。
准备如下的数据,我们后续会通过下面的数据进行测试
{"name": "王五","phone": "18965423142","idNo": "340111196404076731","addr": "安徽"}{"name": "李四","phone": "12548735495","idNo": "140321196804130553","addr": "山西"}{"name": "张三","phone": "13898987656","idNo": "230303197201215332","addr": "黑龙江"}
接下来我们会通过JPA来管理实体对象(表),JPA、MyBatis的CRUD操作。
加密算法组件


