场景
为防止数据泄露,需要在插入等操作时将某表的字段在数据库中加密存储,在需要查询使用时明文显示。
Sharding Sphere
ShardingSphere是一套开源的分布式数据库中间件解决方案组成的生态圈,
它由Sharding-JDBC、Sharding-Proxy和Sharding-Sidecar(计划中)这3款相互独立的产品组成。
他们均提供标准化的数据分片、分布式事务和数据库治理功能,可适用于如Java同构、异构语言、云原生
等各种多样化的应用场景。
ShardingSphere定位为关系型数据库中间件,旨在充分合理地在分布式的场景下利用关系型数据库的计算和存储能力,
而并非实现一个全新的关系型数据库。 它与NoSQL和NewSQL是并存而非互斥的关系。
NoSQL和NewSQL作为新技术探索的前沿,放眼未来,拥抱变化,是非常值得推荐的。
数据脱敏只是其中一个模块,下面是官方文档说明。
数据脱敏 :: ShardingSphere
注:
博客:
霸道流氓气质的博客_CSDN博客-C#,架构之路,SpringBoot领域博主
实现
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,则查询为密文