数据脱敏 #
随着《网络安全法》的颁布施行,对个人隐私数据的保护已经上升到法律层面。传统的应用系统普遍缺少对个人隐私数据的保护措施。数据脱敏,可实现在不需要对生产数据库中的数据进行任何改变的情况下,依据用户定义的脱敏规则,对生产数据库返回的数据进行专门的加密、遮盖和替换,确保生产环境的敏感数据能够得到保护。
挑战和目标 #
在真实业务场景中,相关业务开发团队则往往需要根据脱敏需求,自行实现并维护一套脱敏功能,而脱敏功能往往是耦合在各个业务逻辑中,不同的业务系统难以复用,而当脱敏场景发生改变时,自行维护的脱敏功能往往又面临着重构或修改的风险。
根据业界对脱敏的需求及业务改造痛点,提供了一套完整、安全、透明化、低改造成本的数据脱敏整合解决方案,是 SphereEx-DBPlusEngine 数据脱敏模块的主要设计目标。
目前 SphereEx-DBPlusEngine 数据脱敏插件所支持的数据库产品为 MySQL、PostgreSQL、openGauss、SQLServer、Oracle、Hive 和 Presto 等,具体支持版本如下。
数据库 | 版本支持 | |
---|---|---|
1 | MySQL | 5.7.x ~ 8.x |
2 | PostgreSQL | 9.6 及以上版本 |
3 | openGauss | 2.1.0 及以上版本 |
4 | SQLServer | 15.0 及以上版本 |
5 | Oracle | 10g 及以上版本 |
6 | Hive | 2.3.2 |
7 | Presto | 0.181, 0.272 |
应用场景 #
不论是快速上线新业务,还是已经上线的成熟业务,都可以接入 SphereEx-DBPlusEngine 脱敏功能,快速地完成脱敏规则的配置。客户无需开发耦合于业务系统的脱敏功能,不需要改动任何业务逻辑和 SQL 就能够透明化地使用脱敏功能。
使用限制 #
脱敏列只支持字符串类型,不支持其他非字符串类型。 已配置脱敏的表上创建的视图,无法使用加解密功能
处理流程 #
SphereEx-DBPlusEngine 通过对用户查询的 SQL 进行解析,并依据用户提供的脱敏规则对 SQL 执行结果进行装饰,从而实现对原文数据进行脱敏。
整体架构 #
脱敏模块将用户发起的 SQL 进行拦截,并通过 SQL 语法解析器进行解析、执行,再依据用户传入的脱敏规则,找出需要脱敏的字段和所使用的脱敏算法对查询结果进行装饰,返回给客户端。
脱敏规则 #
在详解整套流程之前,我们需要先了解下脱敏规则与配置,这是认识整套流程的基础。脱敏配置主要分为三部分:数据源配置,脱敏算法配置,脱敏表配置,脱敏规则创建即可生效。
数据源配置:指数据源配置。
脱敏算法配置:指使用什么脱敏算法。目前 SphereEx-DBPlusEngine 内置了多种脱敏算法:MD5
、KEEP_FIRST_N_LAST_M
、KEEP_FROM_X_TO_Y
、MASK_FIRST_N_LAST_M
、MASK_FROM_X_TO_Y
、MASK_BEFORE_SPECIAL_CHARS
、MASK_AFTER_SPECIAL_CHARS
、SphereEx:PERSONAL_IDENTITY_NUMBER_RANDOM_REPLACE
、SphereEx:MILITARY_IDENTITY_NUMBER_RANDOM_REPLACE
、SphereEx:TELEPHONE_RANDOM_REPLACE
、SphereEx:LANDLINE_NUMBER_RANDOM_REPLACE
、SphereEx:UNIFIED_CREDIT_CODE_RANDOM_REPLACE
和 GENERIC_TABLE_RANDOM_REPLACE
。用户还可以通过实现 SphereEx-DBPlusEngine 提供的接口,自行实现一套脱敏算法。
关于算法类型的详情,请参见内置脱敏算法列表。
脱敏表配置:用于告诉 SphereEx-DBPlusEngine 数据表里哪个列用于数据脱敏、使用什么算法脱敏。
逻辑列:用于计算脱敏列的逻辑名称,它是 SQL 中列的逻辑标识。
脱敏处理过程 #
举例说明,假如数据库里有一张表叫做 t_user
,这张表里有一个字段 phone_number
使用 MASK_FROM_X_TO_Y
进行算法处理,SphereEx-DBPlusEngine 不会改变数据存储,只会按脱敏算法对结果进行装饰,从而达到脱敏的效果
如下图所示:
配置示例 #
下面通过对电话号字段脱敏的简单的例子,来了解 SphereEx-DBPlusEngine 的配置和使用。
详细语法说明请参考数据脱敏 DistSQL。
- 在 MySQL 中创建数据库 demo_ds_0
mysql> CREATE DATABASE demo_ds_0;
- 在 SphereEx-DBPlusEngine 中创建名为 mask_db 的逻辑库
mysql> create database mask_db;
mysql> show databases;
mysql> use mask_db;
mysql> REGISTER STORAGE UNIT ds_0 (
HOST="192.168.xx.103",
PORT=3306,
DB="demo_ds_0",
USER="test",
PASSWORD="Test@123"
);
mysql> SHOW STORAGE UNITS;
- 在 mask_db 中创建测试表,并插入数据
mysql> CREATE TABLE t_mask (
`id` int(11) NOT NULL,
`telephone` varchar(64) DEFAULT NULL,
`address` varchar(64) DEFAULT NULL,
PRIMARY KEY (`id`)
);
Query OK, 0 rows affected (0.22 sec)
mysql> INSERT INTO t_mask (id, telephone, address) VALUES
(1,'13888888888','Beijing'),
(2,'18000100001','Nanjing'),
(3,'17337312345','Hangzhou'),
(4,'13654054321','Chengdu');
Query OK, 4 rows affected (0.06 sec)
- 创建脱敏规则
将 telephone
字段中 4 到 7 位脱敏为 *
。
mysql> CREATE MASK RULE t_mask (
COLUMNS(
(NAME=telephone,TYPE(NAME='KEEP_FIRST_N_LAST_M',PROPERTIES("first-n"=3,"last-m"=4,"replace-char"="*"))),
(NAME=address,TYPE(NAME='MD5'))
));
Query OK, 0 rows affected (0.36 sec)
mysql> SHOW MASK RULES;
+--------+-----------+---------------------+-----------------------------------+
| table | column | algorithm_type | algorithm_props |
+--------+-----------+---------------------+-----------------------------------+
| t_mask | telephone | KEEP_FIRST_N_LAST_M | first-n=3,replace-char=*,last-m=4 |
| t_mask | address | MD5 | |
+--------+-----------+---------------------+-----------------------------------+
2 rows in set (0.15 sec)
- 查询脱敏后的数据
mysql> SELECT * FROM t_mask;
+----+-------------+----------------------------------+
| id | telephone | address |
+----+-------------+----------------------------------+
| 1 | 138****8888 | 78fb473f134eed43c959f9ebdeeb4050 |
| 2 | 180****0001 | 080fa4ae8318b4cc0be7f76fefe4838e |
| 3 | 173****2345 | 95e9c48630a252346b29cd52b365d3e2 |
| 4 | 136****4321 | f4aa575f70b3f78887deb96ce611b187 |
+----+-------------+----------------------------------+
4 rows in set (0.00 sec)
可见,电话号码部分数字已经展示为星号,和预期一致。
- 基于上述脱敏配置,变更后再进行校验
只展示 telephone 字段的首尾内容,中间用 ?
展示。
mysql> ALTER MASK RULE t_mask (
COLUMNS(
(NAME=telephone,TYPE(NAME='KEEP_FIRST_N_LAST_M',PROPERTIES("first-n"=1,"last-m"=1,"replace-char"="?"))),
(NAME=address,TYPE(NAME='MD5'))
));
Query OK, 0 rows affected (0.27 sec)
mysql> SHOW MASK RULES;
+--------+-----------+---------------------+-----------------------------------+
| table | column | algorithm_type | algorithm_props |
+--------+-----------+---------------------+-----------------------------------+
| t_mask | telephone | KEEP_FIRST_N_LAST_M | first-n=1,last-m=1,replace-char=? |
| t_mask | address | MD5 | |
+--------+-----------+---------------------+-----------------------------------+
2 rows in set (0.04 sec)
- 再次查询进行确认
mysql> SELECT * FROM t_mask;
+----+-------------+----------------------------------+
| id | telephone | address |
+----+-------------+----------------------------------+
| 1 | 1?????????8 | 9bd8ad60a4e25ee4f07b545c65e268c6 |
| 2 | 1?????????1 | 99116a7dc5f614c84f71834820505048 |
| 3 | 1?????????5 | 7e2d6cf42a4f42358373f9363f341d3a |
| 4 | 1?????????1 | f418a8bcbe75adb8721a9eacf16eeb0d |
+----+-------------+----------------------------------+
4 rows in set (0.01 sec)
- 删除过敏规则,查看数据
mysql> DROP MASK RULE t_mask;
Query OK, 0 rows affected (0.09 sec)
mysql> SHOW MASK RULES;
Empty set (0.00 sec)
mysql> SELECT * FROM t_mask;
+----+-------------+----------+
| id | telephone | address |
+----+-------------+----------+
| 1 | 13888888888 | Beijing |
| 2 | 18000100001 | Nanjing |
| 3 | 17337312345 | Hangzhou |
| 4 | 13654054321 | Chengdu |
+----+-------------+----------+
4 rows in set (0.01 sec)
删除过敏规则后,可正常对数据进行检索,符合预期。