Logo
数据脱敏

数据脱敏 #

随着《网络安全法》的颁布施行,对个人隐私数据的保护已经上升到法律层面。传统的应用系统普遍缺少对个人隐私数据的保护措施。数据脱敏,可实现在不需要对生产数据库中的数据进行任何改变的情况下,依据用户定义的脱敏规则,对生产数据库返回的数据进行专门的加密、遮盖和替换,确保生产环境的敏感数据能够得到保护。

挑战和目标 #

在真实业务场景中,相关业务开发团队则往往需要根据脱敏需求,自行实现并维护一套脱敏功能,而脱敏功能往往是耦合在各个业务逻辑中,不同的业务系统难以复用,而当脱敏场景发生改变时,自行维护的脱敏功能往往又面临着重构或修改的风险。

根据业界对脱敏的需求及业务改造痛点,提供了一套完整、安全、透明化、低改造成本的数据脱敏整合解决方案,是 SphereEx-DBPlusEngine 数据脱敏模块的主要设计目标。

应用场景 #

不论是快速上线新业务,还是已经上线的成熟业务,都可以接入 SphereEx-DBPlusEngine 脱敏功能,快速地完成脱敏规则的配置。客户无需开发耦合于业务系统的脱敏功能,不需要改动任何业务逻辑和 SQL 就能够透明化地使用脱敏功能。

使用限制 #

脱敏列只支持字符串类型,不支持其他非字符串类型。

处理流程 #

SphereEx-DBPlusEngine 通过对用户查询的 SQL 进行解析,并依据用户提供的脱敏规则对 SQL 执行结果进行装饰,从而实现对原文数据进行脱敏。

整体架构 #

数据脱敏架构

脱敏模块将用户发起的 SQL 进行拦截,并通过 SQL 语法解析器进行解析、执行,再依据用户传入的脱敏规则,找出需要脱敏的字段和所使用的脱敏算法对查询结果进行装饰,返回给客户端。

脱敏规则 #

在详解整套流程之前,我们需要先了解下脱敏规则与配置,这是认识整套流程的基础。脱敏配置主要分为三部分:数据源配置,脱敏算法配置,脱敏表配置,脱敏规则创建即可生效

数据脱敏规则

数据源配置:指数据源配置。

脱敏算法配置:指使用什么脱敏算法。目前 SphereEx-DBPlusEngine 内置了多种脱敏算法:MD5KEEP_FIRST_N_LAST_MKEEP_FROM_X_TO_YMASK_FIRST_N_LAST_MMASK_FROM_X_TO_YMASK_BEFORE_SPECIAL_CHARSMASK_AFTER_SPECIAL_CHARSPERSONAL_IDENTITY_NUMBER_RANDOM_REPLACEMILITARY_IDENTITY_NUMBER_RANDOM_REPLACETELEPHONE_RANDOM_REPLACE。用户还可以通过实现 SphereEx-DBPlusEngine 提供的接口,自行实现一套脱敏算法。

关于算法类型的详情,请参见内置脱敏算法列表

脱敏表配置:用于告诉 SphereEx-DBPlusEngine 数据表里哪个列用于数据脱敏、使用什么算法脱敏。

逻辑列:用于计算脱敏列的逻辑名称,它是 SQL 中列的逻辑标识。

脱敏处理过程 #

举例说明,假如数据库里有一张表叫做 t_user,这张表里有一个字段 phone_number 使用 MASK_FROM_X_TO_Y 进行算法处理,SphereEx-DBPlusEngine 不会改变数据存储,只会按脱敏算法对结果进行装饰,从而达到脱敏的效果

如下图所示:

数据脱敏过程

配置示例 #

下面通过对电话号字段脱敏的简单的例子,来了解 SphereEx-DBPlusEngine 的配置和使用。

详细语法说明请参考数据脱敏 DistSQL

  1. 在 MySQL 中创建数据库 demo_ds_0
copymysql> CREATE DATABASE demo_ds_0;
  1. 在 SphereEx-DBPlusEngine 中创建名为 mask_db 的逻辑库
copymysql> 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;
  1. 在 mask_db 中创建测试表,并插入数据
copymysql> 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)
  1. 创建脱敏规则

telephone 字段中 4 到 7 位脱敏为 *

copymysql> 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)
  1. 查询脱敏后的数据
copymysql> 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)

可见,电话号码部分数字已经展示为星号,和预期一致。

  1. 基于上述脱敏配置,变更后再进行校验

只展示 telephone 字段的首尾内容,中间用 ? 展示。

copymysql> 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)
  1. 再次查询进行确认
copymysql> 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)
  1. 删除过敏规则,查看数据
copymysql> 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)

删除过敏规则后,可正常对数据进行检索,符合预期。