1、需求背景

安全控制一直是治理的重要环节,数据加密属于安全控制的范畴。 无论对互联网公司还是传统行业来说,数据安全一直是极为重视和敏感的话题。 数据加密是指对某些敏感信息通过加密规则进行数据的变形,实现敏感隐私数据的可靠保护。 涉及客户安全数据或者一些商业性敏感数据,如身份证号、手机号、卡号、客户号等个人信息按照相关部门规定,都需要进行数据加密。

对于数据加密的需求,在现实的业务场景中存在如下情况:

  • 密码样式的文本:安全部门规定需将涉及用户敏感信息,例如银行、手机号码等进行加密后存储到数据库,在使用的时候再进行解密处理。

在真实业务场景中,相关业务开发团队则往往需要针对公司安全部门需求,
自行实行并维护一套加解密系统。 而当加密场景发生改变时,自行维护的加密系统往往又面临着重构或修改风险。
此外,对于已经上线的业务在不修改业务逻辑和 SQL 的情况下,透明化、安全低风险地实现无缝进行加密改造也相对复杂。

2、项目实战

1、引入ShardingSphere

1
2
3
4
5
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-jdbc-core</artifactId>
<version>5.3.2</version>
</dependency>

2、新增加密配置

application.yaml 配置文件修改配置,将数据库驱动变更为 ShardingSphere Driver

1
2
3
4
spring:
datasource:
driver-class-name: org.apache.shardingsphere.driver.ShardingSphereDriver
url: jdbc:shardingsphere:classpath:shardingsphere-config.yaml

并配置 shardingsphere-config.yaml 相关配置。为了方便大家理解,这篇文章只讲敏感数据信息加密存储

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# 配置数据源,底层被 ShardingSphere 进行了代理
dataSources:
ds_0:
dataSourceClassName: com.zaxxer.hikari.HikariDataSource
driverClassName: com.mysql.cj.jdbc.Driver
jdbcUrl: jdbc:mysql://127.0.0.1:3306/12306_user_0?useUnicode=true&characterEncoding=UTF-8&rewriteBatchedStatements=true&allowMultiQueries=true&serverTimezone=Asia/Shanghai
username: root
password: root

rules:
# 数据加密存储规则
- !ENCRYPT
# 需要加密的表集合
tables:
# 用户表
t_user:
# 用户表中哪些字段需要进行加密
columns:
# 身份证字段,逻辑字段,不一定是在数据库中真实存在
id_card:
# 身份证字段存储的密文字段,这个是数据库中真实存在的字段
cipherColumn: id_card
# 身份证字段加密算法
encryptorName: common_encryptor
phone:
cipherColumn: phone
encryptorName: common_encryptor
mail:
cipherColumn: mail
encryptorName: common_encryptor
address:
cipherColumn: address
encryptorName: common_encryptor
# 是否按照密文字段查询
queryWithCipherColumn: true
# 加密算法
encryptors:
# 自定义加密算法名称
common_encryptor:
# 加密算法类型
type: AES
props:
# AES 加密密钥
aes-key-value: d6oadClrrb9A3GWo
props:
sql-show: true

3、最终效果如下

当配置好之后,执行对于的插入逻辑,新插入一条用户信息,在应用程序里还是明文,经过 ShardingSphere 代理后,存储数据库时,就已经是密文的了。可以通过Stream-Query来配置打印执行sql

原始SQL :

1
insert into t_user (id_card, phone, mail, address) values ('34020xx023081xx338', '1x60111xx983', 'mading@axxche.org', 'xx东城x');

代理后SQL :

1
insert into t_user (id_card, phone, mail, address) values ('YUvr+8Xf17VCgGonU2WXqmKuhB5FMazUEbh3y+h0B38=', 'MZObk+5TeYPLHtP2A6+aiw==', 'vX/5iWTyfAvMJMt+ioipj9vd6cnZ4rz4qKBAXQ9C9oU=', 'vX/5iWTyfAvMJMt+ioipj9vd6cnZ4rz4qKBAXQ9C9oU=');

注:

ShardingSphere 在执行查询语句时,如果涉及到相关加密表,会自动将加密数据转换为明文数据,也就是会把 YUvr+8Xf17VCgGonU2WXqmKuhB5FMazUEbh3y+h0B38= 转换为 34020xx023081xx338.由此形成加密敏感信息落库闭环。