SpringBoot中整合Sharding Sphere实现数据加解密/数据脱敏/数据库密文,查询明文

发布时间 2023-07-15 17:42:40作者: 霸道流氓

场景

为防止数据泄露,需要在插入等操作时将某表的字段在数据库中加密存储,在需要查询使用时明文显示。

Sharding Sphere

ShardingSphere是一套开源的分布式数据库中间件解决方案组成的生态圈,

它由Sharding-JDBC、Sharding-Proxy和Sharding-Sidecar(计划中)这3款相互独立的产品组成。

 他们均提供标准化的数据分片、分布式事务和数据库治理功能,可适用于如Java同构、异构语言、云原生

等各种多样化的应用场景。

ShardingSphere定位为关系型数据库中间件,旨在充分合理地在分布式的场景下利用关系型数据库的计算和存储能力,

而并非实现一个全新的关系型数据库。 它与NoSQL和NewSQL是并存而非互斥的关系。

NoSQL和NewSQL作为新技术探索的前沿,放眼未来,拥抱变化,是非常值得推荐的。

数据脱敏只是其中一个模块,下面是官方文档说明。

https://shardingsphere.apache.org/document/legacy/4.x/document/cn/manual/sharding-jdbc/usage/encrypt/

注:

博客:
https://blog.csdn.net/badao_liumang_qizhi

实现

1、新建SpringBoot项目并引入依赖

        <dependency>
            <groupId>org.apache.shardingsphere</groupId>
            <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
            <version>4.1.1</version>
        </dependency>

2、修改yml配置文件中原数据源配置为shardingsphere并进行加密等相关规则配置

修改前的数据源配置

# 数据源
spring:
  application:
    name: apiDataDesensitizationDemo
  datasource:
   url:jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver
    dbcp2:
      min-idle: 5                                # 数据库连接池的最小维持连接数
      initial-size: 5                            # 初始化连接数
      max-total: 5                               # 最大连接数
      max-wait-millis: 150                       # 等待连接获取的最大超时时间

修改后的数据源配置

# 数据源
spring:
  application:
    name: apiDataDesensitizationDemo
  shardingsphere:
    datasource:
      names: ds0
      ds0:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.jdbc.Driver
       jdbc-url:jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
        username: root
        password: 123456

添加加密相关规则配置

# 数据源
spring:
  application:
    name: apiDataDesensitizationDemo
  shardingsphere:
    datasource:
      names: ds0
      ds0:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.jdbc.Driver
       jdbc-url:jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
        username: root
        password: 123456

    encrypt:
      tables:
        t_user:
          columns:
            name:
              #plainColumn: pwd_plain
              cipherColumn: name
              encryptor: pwdEncrypt
      encryptors:
        pwdEncrypt:
          type: AES
          props:
            aes:
              key:
                value: 123456
    props:
      query:
        with:
          cipher:
            column: true #是否使用密文列查询,false 则查询时返回密文,true则查询时返回明文

注意这里的配置文件中,表示要对t_user表的name属性进行加密,并且指定密文存储列也为name,

如果需要存储明文,则放开配置plainColumn。

后面是指定加密器,以及类型为自带的AES,秘钥为123456。

后面的配置#是否使用密文列查询,false 则查询时返回密文,true则查询时返回明文

3、新建测试表t_user

 

然后根据此表生成各层代码,此处省略。

只附实体类代码

@Data
public class User implements Serializable {

    private static final long serialVersionUID = -5514139686858156155L;

    private Integer id;

    private Integer userId;

    private String name;

    private Integer age;

}

4、新建controller进行测试查询和查询

@RequestMapping("user")
@RestController
public class UserController {

    @Autowired
    private UserService userService;

    @RequestMapping("save")
    public String save() {
        User user = new User();
        user.setUserId(new Random().nextInt( 1000 ) + 1);
        user.setName("张三"+user.getUserId());
        user.setAge(new Random().nextInt( 80 ) + 1);
        userService.insert(user);
        return "save success";
    }

    @RequestMapping("findAll")
    public String findAll() {
        List<User> all = userService.findAll();
        return all.toString();
    }

}

启动并测试插入,结果如上图,数据库中存储为密文。

然后调用查询,当上面的配置为true时,此时查询返回明文

 

将其改为false,则查询为密文