本文首发于 Apache ShardingSphere 微信公众号,欢迎关注公众号,后续将会有更多技术分享。
背景
随着《网络安全法》的颁布施行,对个人隐私数据的保护已经上升到法律层面。传统的应用系统普遍缺少对个人隐私数据的保护措施。数据脱敏,可以实现在不需要对生产数据库中的数据进行任何改变的情况下,依据用户的角色、职责和其他定义规则,对生产数据库返回的数据进行专门的屏蔽、加密、隐藏和审计,确保业务用户、外包用户、运维人员、兼职雇员、合作伙伴、数据分析师、研发、测试和顾问,都能够恰如其分地访问生产环境的敏感数据。
根据业界的相关经验,数据脱敏通常可以分为静态脱敏和动态脱敏。静态脱敏是指通过脱敏任务,针对数据库系统使用脱敏算法对敏感数据进行遮盖、加密或替换,并将脱敏后的数据保存到目标位置。动态脱敏相对于静态脱敏则更加灵活,可以针对每次查询的数据进行脱敏,脱敏数据不需要落地保存。ShardingSphere 5.3.1 版本提供了动态数据脱敏功能,用户通过 ShardingSphere 进行查询,ShardingSphere 会根据用户预先配置的脱敏规则,在返回结果前根据脱敏算法进行处理,再将脱敏后的数据返回给用户。
实现方案
脱敏与微内核
基于 ShardingSphere 微内核及可插拔架构,数据脱敏功能只需要实现结果归并引擎 SPI 就可以实现功能的灵活扩展。如下图所示,ShardingSphere 微内核中已经包含了 SQL 解析
、SQL 路由
、SQL 执行
等核心逻辑,ShardingSphere 5.3.1 版本提供的动态脱敏功能,只是对其他功能查询结果的增强处理,因此只需要实现归并引擎中的 ResultDecoratorEngine 和 ResultDecorator 即可实现脱敏功能。
为了实现数据脱敏功能,本次在 features 模块中增加 shardingsphere-mask
模块,该模块包含了 shardingsphere-mask-api
、shardingsphere-mask-core
和 shardingsphere-mask-distsql
,各个模块的作用如下:
shardingsphere-mask-api
:脱敏 API 模块,包含了脱敏功能的 Rule 配置,以及脱敏算法 SPI 接口;shardingsphere-mask-core
:脱敏功能的核心模块,包含了 Rule 的初始化逻辑,脱敏算法实现以及结果归并装饰器实现逻辑;shardingsphere-mask-distsql
:脱敏功能的 DistSQL 模块,用户可以通过 DistSQL 动态地修改脱敏规则;
除了内核流程之外,脱敏功能在内核中的定位也同样值得我们关注。我们知道,ShardingSphere 强大的可插拔架构,允许我们任意地组合叠加内核功能,新增的脱敏功能也不例外,用户可以单独使用脱敏功能,也可以将脱敏和分片、加密等功能叠加使用,组成更加完善的分布式数据库解决方案。
下图展示了目前 ShardingSphere 内核功能的关系,总体上可以将内核功能划分为三个级别:基于列级别的功能、基于表级别的功能和基于数据源级别的功能。基于列级别的功能包括了数据加密和数据脱敏,主要针对列进行增强处理,基于表级别的功能则包含了数据分片和内置的单表管理,基于数据源级别的功能目前最为丰富,包括了 SphereEx 商业版提供的双写功能,ShardingSphere 开源版本提供的读写分离、高可用发现和影子库功能,这些都是围绕数据库流量治理相关的功能。ShardingSphere 会按照这三个层级关系依次进行处理,而在每一个层级内部,则是根据 Order 进行处理,例如:当用户同时使用加密和脱敏功能时,会优先处理加密逻辑,将存储在数据库中的密文数据进行解密,然后再使用脱敏算法进行数据脱敏。
脱敏 YAML API & DistSQL
介绍完脱敏和微内核的关系后,我们再来了解下脱敏功能的 API 和 DistSQL,用户可以基于 YAML 配置或者使用 DistSQL 进行脱敏规则的配置。首先,我们来了解下 YAML API 的配置方式,用户只需要在 - !MASK
下的 tables 中配置脱敏列及脱敏算法即可,maskAlgorithm 定义的脱敏算法名称,需要与 maskAlgorithms 中的名称保持一致。
脱敏 YAML API 主要配置属性如下:
- maskAlgorithm:指定脱敏算法,动态脱敏根据脱敏算法进行数据处理;
1 | databaseName: mask_db |
此外,考虑到一些用户存在动态更新脱敏规则的需求,ShardingSphere 5.3.1 版本同时提供了脱敏 DistSQL 的支持,满足用户在运行阶段动态更新脱敏规则的需要,脱敏 DistSQL 语法如下,包含了创建、修改、删除和查看脱敏规则等常用的 DistSQL 语句。
1 | -- 创建脱敏规则 |
更多详细的 DistSQL 语法说明,请参考数据脱敏 DistSQL 文档。
内置脱敏算法
ShardingSphere 5.3.1 本次发布也包含了大量内置的脱敏算法,算法基于 MaskAlgorithm SPI 接口实现,用户可以根据自己的业务需求进行灵活扩展。
1 | /** |
内置的脱敏算法主要可以分为三类,哈希脱敏、遮盖脱敏和替换脱敏,具体算法清单如下:
分类 | 名称 | 说明 |
---|---|---|
哈希脱敏 | MD5 | 基于 MD5 的数据脱敏算法 |
遮盖脱敏 | KEEP_FIRST_N_LAST_M | 保留前 n 后 m 数据脱敏算法 |
KEEP_FROM_X_TO_Y | 保留自 x 至 y 数据脱敏算法 | |
MASK_FIRST_N_LAST_M | 遮盖前 n 后 m 数据脱敏算法 | |
MASK_FROM_X_TO_Y | 遮盖自 x 至 y 数据脱敏算法 | |
MASK_BEFORE_SPECIAL_CHARS | 特殊字符前遮盖数据脱敏算法 | |
MASK_AFTER_SPECIAL_CHARS | 特殊字符后遮盖数据脱敏算法 | |
替换脱敏 | PERSONAL_IDENTITY_NUMBER_RANDOM_REPLACE | 身份证号随机替换数据脱敏算法 |
MILITARY_IDENTITY_NUMBER_RANDOM_REPLACE | 军官证随机替换数据脱敏算法 | |
TELEPHONE_RANDOM_REPLACE | ⼿机号随机替换数据脱敏算法 |
脱敏算法目前还在不断完善中,更多关于算法参数的说明,请参考脱敏算法文档,也欢迎大家积极参与贡献,一起完善脱敏算法。
脱敏实战
在最后一个部分,我们通过一个实战来具体了解下数据脱敏功能。通常对于企业内部的敏感数据,我们会选择数据脱敏和数据加密配合使用,Database 层存储数据时采用数据加密进行保护,避免数据丢失造成安全问题。在数据查询阶段,则会根据规则进行数据解密和数据脱敏,避免敏感数据直接展示。因此,本文实战部分选择了数据脱敏和数据加密叠加使用的场景,通过 DistSQL 进行动态更新,向大家展示下数据脱敏功能的实际效果。
首先,我们下载 ShardingSphere Proxy 5.3.1 版本 ,并配置 server.yaml
进行空启动,然后使用 mysql -u root -h 127.0.0.1 -P 3307 -p -c -A
连接 Proxy,并执行 CREATE DATABASE mask_db;
创建脱敏逻辑数据库。
1 | -- 创建脱敏逻辑数据库 |
创建完逻辑数据库后,我们使用 DistSQL 注册存储资源,并初始化脱敏和加密规则。
1 | -- 注册存储资源 |
脱敏规则和加密规则创建完成后,我们可以通过 DistSQL SHOW
语句查看脱敏和加密规则:
1 | -- 查看脱敏规则 |
创建完规则后,我们创建如下的 t_user 表并进行数据初始化:
1 | DROP TABLE IF EXISTS t_user; |
完成了数据初始化后,我们先通过 mysql -u root -h 127.0.0.1 -P 3306 -p -c -A
直接 MySQL 数据库,查看底层数据库 t_user 表中存储的数据,可以看到 MySQL 中存储的是加密之后的数据,敏感数据在数据库存储层得到了有效的保护。
1 | mysql> SELECT * FROM t_user; |
确认完数据加密的效果后,我们再对数据脱敏功能进行一个简单的测试,下面的测试 CASE 包含了简单的 SELECT 查询
、关联查询
、子查询
等用户日常操作的语句,可以看到 password 字段使用 MD5 哈希脱敏,email 字段使用了 MASK_BEFORE_SPECIAL_CHARS 遮盖脱敏,telephone 字段则使用了 KEEP_FIRST_N_LAST_M 遮盖脱敏。
1 | -- 简单 SELECT 查询 |
我们使用 DistSQL 修改脱敏规则,将 password 字段使用的 MD5 哈希脱敏增加可选参数 salt,telephone 字段的脱敏算法修改为 TELEPHONE_RANDOM_REPLACE 手机号随机替换脱敏算法。
1 | ALTER MASK RULE t_user ( |
修改完成后,再次进行查询测试,可以看到由于 salt 值的变化,password 字段 MD5 脱敏的结果发生了变化,而 telephone 字段由于使用了手机号随机替换脱敏算法,脱敏的结果也变为号段位之后随机生成。
1 | mysql> SELECT * FROM t_user WHERE user_id = 10; |
最后,我们执行 DROP MASK RULE t_user;
语句将脱敏规则删除,此时再进行查询可以返回原始明文结果。
1 | mysql> SELECT * FROM t_user WHERE user_id = 10; |
结语
Apache ShardingSphere 5.3.1 新增的动态数据脱敏功能,是对 ShardingSphere 数据安全方案的进一步补充和完善,未来数据脱敏将会尝试和用户权限、SQL 审计等功能进行结合,根据企业内部的角色划分,进行不同维度的数据脱敏处理。欢迎社区的同学积极参与进来,共同提升 Apache ShardingSphere 的脱敏功能,为社区提供更好的使用体验。