经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » Spring » 查看文章
SpringBoot+ Sharding Sphere 轻松实现数据库字段加解密
来源:cnblogs  作者:潘志的研发笔记  时间:2024/7/22 16:47:07  对本文有异议

一、介绍

在实际的软件系统开发过程中,由于业务的需求,在代码层面实现数据的脱敏还是远远不够的,往往还需要在数据库层面针对某些关键性的敏感信息,例如:身份证号、银行卡号、手机号、工资等信息进行加密存储,实现真正意义的数据混淆脱敏,以满足信息安全的需要。

那在实际的业务开发过程中,我们如何快速实现呢?

今天通过这篇文章,我们一起来了解一下如何在 Spring Boot 中快速实现数据的加解密功能。废话不多说了,直接撸代码!

二、方案实践

在 Spring Boot 生态中,有一个非常厉害的开源框架:Apache ShardingSphere。

它是一款分布式 SQL 事务和查询引擎,可通过数据分片、弹性伸缩、加密等能力对任意数据库进行增强。我们可以利用它的数据脱敏模块,快速实现 SQL 字段的加解密操作。

如果当前项目是采用 Spring Boot 开发的,可以实现无缝集成,对原系统的改造会非常少。

下面以用户表为例,一起了解一下ShardingSphere的数据加解密的实现过程!

2.1、创建用户表

首先,在数据库中创建一张用户表,示例脚本如下!

  1. CREATE TABLE user (
  2. id bigint(20) NOT NULL COMMENT '用户ID',
  3. email varchar(255) NOT NULL DEFAULT '' COMMENT '邮件',
  4. nick_name varchar(255) DEFAULT NULL COMMENT '昵称',
  5. pass_word varchar(255) NOT NULL DEFAULT '' COMMENT '二次密码',
  6. reg_time varchar(255) NOT NULL DEFAULT '' COMMENT '注册时间',
  7. user_name varchar(255) NOT NULL DEFAULT '' COMMENT '用户名',
  8. salary varchar(255) DEFAULT NULL COMMENT '基本工资',
  9. PRIMARY KEY (id) USING BTREE
  10. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

2.2、创建 springboot 项目并添加依赖包

接着,创建一个 Spring Boot 项目,并添加相关的依赖包,示例如下:

  1. <dependencies>
  2. <!--spring boot核心-->
  3. <dependency>
  4. <groupId>org.springframework.boot</groupId>
  5. <artifactId>spring-boot-starter</artifactId>
  6. </dependency>
  7. <!--spring boot 测试-->
  8. <dependency>
  9. <groupId>org.springframework.boot</groupId>
  10. <artifactId>spring-boot-starter-test</artifactId>
  11. <scope>test</scope>
  12. </dependency>
  13. <!--springmvc web-->
  14. <dependency>
  15. <groupId>org.springframework.boot</groupId>
  16. <artifactId>spring-boot-starter-web</artifactId>
  17. </dependency>
  18. <!--mysql 数据源-->
  19. <dependency>
  20. <groupId>mysql</groupId>
  21. <artifactId>mysql-connector-java</artifactId>
  22. </dependency>
  23. <!--mybatis 支持-->
  24. <dependency>
  25. <groupId>org.mybatis.spring.boot</groupId>
  26. <artifactId>mybatis-spring-boot-starter</artifactId>
  27. <version>2.0.0</version>
  28. </dependency>
  29. <!--shardingsphere数据分片、脱敏工具-->
  30. <dependency>
  31. <groupId>org.apache.shardingsphere</groupId>
  32. <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
  33. <version>4.1.0</version>
  34. </dependency>
  35. <dependency>
  36. <groupId>org.apache.shardingsphere</groupId>
  37. <artifactId>sharding-jdbc-spring-namespace</artifactId>
  38. <version>4.1.0</version>
  39. </dependency>
  40. </dependencies>

2.3、添加相关配置

application.properties文件中,添加shardingsphere相关配置,即可实现针对某个表进行脱敏

  1. server.port=8080
  2. logging.path=log
  3. #shardingsphere数据源集成
  4. spring.shardingsphere.datasource.name=ds
  5. spring.shardingsphere.datasource.ds.type=com.zaxxer.hikari.HikariDataSource
  6. spring.shardingsphere.datasource.ds.driver-class-name=com.mysql.cj.jdbc.Driver
  7. spring.shardingsphere.datasource.ds.jdbc-url=jdbc:mysql://127.0.0.1:3306/test
  8. spring.shardingsphere.datasource.ds.username=xxxx
  9. spring.shardingsphere.datasource.ds.password=xxxx
  10. #加密方式、密钥配置
  11. spring.shardingsphere.encrypt.encryptors.encryptor_aes.type=aes
  12. spring.shardingsphere.encrypt.encryptors.encryptor_aes.props.aes.key.value=hkiqAXU6Ur5fixGHaO4Lb2V2ggausYwW
  13. #plainColumn表示明文列,cipherColumn表示脱敏列
  14. spring.shardingsphere.encrypt.tables.user.columns.salary.plainColumn=
  15. spring.shardingsphere.encrypt.tables.user.columns.salary.cipherColumn=salary
  16. #spring.shardingsphere.encrypt.tables.user.columns.pass_word.assistedQueryColumn=
  17. spring.shardingsphere.encrypt.tables.user.columns.salary.encryptor=encryptor_aes
  18. #sql打印
  19. spring.shardingsphere.props.sql.show=true
  20. spring.shardingsphere.props.query.with.cipher.column=true
  21. #基于xml方法的配置
  22. mybatis.mapper-locations=classpath:mapper/*.xml

其中有几个的配置信息比较重要,spring.shardingsphere.encrypt.tables是指要脱敏的表,user是表名,salary表示user表中的真实列,其中plainColumn指的是明文列,cipherColumn指的是脱敏列,如果是新工程,只需要配置脱敏列即可!

配置示例如下!

  1. # 用于告诉 ShardingSphere 数据表里哪个列用于存储明文数据
  2. spring.shardingsphere.encrypt.tables.user.columns.salary.plainColumn=
  3. # 用于告诉 ShardingSphere 数据表里哪个列用于存储密文数据
  4. spring.shardingsphere.encrypt.tables.user.columns.salary.cipherColumn=salary
  5. # 用于告诉 ShardingSphere 数据表里哪个列用于存储辅助查询数据
  6. #spring.shardingsphere.encrypt.tables.user.columns.salary.assistedQueryColumn=
  7. # 用于告诉 ShardingSphere 数据表里哪个列使用什么算法加解密
  8. spring.shardingsphere.encrypt.tables.user.columns.salary.encryptor=encryptor_aes

2.4、编写数据持久层

然后,编写一个数据持久层,用于数据的存储和查询操作。

  1. <mapper namespace="com.example.shardingsphere.mapper.UserMapperXml" >
  2. <resultMap id="BaseResultMap" type="com.example.shardingsphere.entity.UserEntity" >
  3. <id column="id" property="id" jdbcType="BIGINT" />
  4. <result column="email" property="email" jdbcType="VARCHAR" />
  5. <result column="nick_name" property="nickName" jdbcType="VARCHAR" />
  6. <result column="pass_word" property="passWord" jdbcType="VARCHAR" />
  7. <result column="reg_time" property="regTime" jdbcType="VARCHAR" />
  8. <result column="user_name" property="userName" jdbcType="VARCHAR" />
  9. <result column="salary" property="salary" jdbcType="VARCHAR" />
  10. </resultMap>
  11. <select id="findAll" resultMap="BaseResultMap">
  12. SELECT * FROM user
  13. </select>
  14. <insert id="insert" parameterType="com.example.shardingsphere.entity.UserEntity">
  15. INSERT INTO user(id,email,nick_name,pass_word,reg_time,user_name, salary)
  16. VALUES(#{id},#{email},#{nickName},#{passWord},#{regTime},#{userName}, #{salary})
  17. </insert>
  18. </mapper>
  1. public interface UserMapperXml {
  2. /**
  3. * 查询所有的信息
  4. * @return
  5. */
  6. List<UserEntity> findAll();
  7. /**
  8. * 新增数据
  9. * @param user
  10. */
  11. void insert(UserEntity user);
  12. }
  1. public class UserEntity {
  2. private Long id;
  3. private String email;
  4. private String nickName;
  5. private String passWord;
  6. private String regTime;
  7. private String userName;
  8. private String salary;
  9. //省略set、get...
  10. }

2.5、单元测试

最后,我们编写一个单元测试,验证一下代码的正确性。

编写启用服务程序

  1. @SpringBootApplication
  2. @MapperScan("com.example.shardingsphere.mapper")
  3. public class ShardingSphereApplication {
  4. public static void main(String[] args) {
  5. SpringApplication.run(ShardingSphereApplication.class, args);
  6. }
  7. }

编写单元测试

  1. @RunWith(SpringJUnit4ClassRunner.class)
  2. @SpringBootTest(classes = ShardingSphereApplication.class)
  3. public class UserTest {
  4. @Autowired
  5. private UserMapperXml userMapperXml;
  6. @Test
  7. public void insert() throws Exception {
  8. UserEntity entity = new UserEntity();
  9. entity.setId(3l);
  10. entity.setEmail("123@123.com");
  11. entity.setNickName("阿三");
  12. entity.setPassWord("123");
  13. entity.setRegTime("2021-10-10 00:00:00");
  14. entity.setUserName("张三");
  15. entity.setSalary("2500");
  16. userMapperXml.insert(entity);
  17. }
  18. @Test
  19. public void query() throws Exception {
  20. List<UserEntity> dataList = userMapperXml.findAll();
  21. System.out.println(JSON.toJSONString(dataList));
  22. }
  23. }

插入数据后,如下图,数据库存储的数据已被加密!

我们继续来看看,运行查询服务,结果如下图,数据被成功解密!

采用配置方式,最大的好处就是直接通过配置脱敏列就可以完成对某些数据表字段的脱敏,非常方便。

三、小结

当需要对某些数据表字段进行脱敏处理的时候,可以采用 Apache ShardingSphere 框架快速实现。

但是有个细节很容易遗漏,那就是字段类型,例如salary字段,根据常规,很容易想到使用数字类型,但是却不是,要知道加密之后的数据都是一串乱码,数字类型肯定是无法存储字符串的,因此在定义的时候,这个要留心一下。

希望以上的案例,能帮助到大家!

示例代码:spring-boot-example-shardingsphere

原文链接:https://www.cnblogs.com/dxflqm/p/18315710

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号