设置动态数据脱敏
SQL Server提供了一种称为动态数据遮蔽(Dynamic Data Masking,DDM)的安全功能,该功能可以防止非授权用户在查询时直接查看敏感数据。动态数据脱敏通过在查询结果中展示部分或全部脱敏的值,而不是实际的数据值,来达到保护数据的目的。
本文档提供通过云数据库RDS界面和原生SQL Server设置动态数据脱敏的操作。
约束限制
- 云数据库RDS for SQL Server如需设置动态数据脱敏,请提交工单申请。
- 仅2016及以上版本支持动态数据脱敏。
- 数据库级别具有CONTROL SERVER或CONTROL权限的用户可以查看原始形式的掩码数据。 这包括管理员用户或角色,例如sysadmin、db_owner等。
- 不能针对以下列类型定义掩码规则:
- 加密列(始终加密)。
- FILESTREAM。
- COLUMN_SET或属于列集一部分的稀疏列。
- 不能在计算列上配置掩码,但如果计算列依赖于带有掩码的列,则计算列将返回已掩码数据。
- 具有数据掩码的列不能作为FULLTEXT索引的密钥。
- PolyBase外部表中的列。
- 如果用户没有UNMASK权限,则无法在配置了动态数据掩码的列上执行弃用的READTEXT、UPDATETEXT和WRITETEXT语句。
- 添加动态数据掩码是作为对基础表的架构更改实现,因此无法对具有依赖关系的列(例如计算列引用的列)执行。
如果针对具有依赖关系的列添加动态数据掩码,会报错:ALTER TABLE ALTER COLUMN _columnname_ failed because one or more objects access this column
如果要解决该限制,可以先删除依赖项,然后添加动态数据屏蔽,再重新创建依赖项。例如:如果依赖项是由于索引依赖于该列,则可以删除索引,然后添加掩码,再重新创建依赖索引。
- 每当投影一个表达式并且该表达式引用了为其定义了数据掩码函数的列时,该表达式也将被屏蔽。无论使用何种函数(默认值、电子邮件、随机、自定义字符串)屏蔽引用的列,都将始终使用默认函数屏蔽生成的表达式。
安全说明
虽然动态数据脱敏在直接访问生产数据库时也能有效防止敏感数据的意外泄露,但需要注意的是,拥有临时查询权限的非特权用户仍可能采用技术手段获取实际数据。
例如查询语句SELECT Salary FROM Employees WHERE Salary = 10000,即使“Salary”字段设置了动态脱敏,查询的结果为“xxx”或其它内容,依旧可以推断出“Salary”的值为“10000”。
操作步骤
- 单击管理控制台左上角的
,选择区域。
- 单击页面左上角的
,选择“数据库 > 云数据库 RDS”,进入RDS信息页面。
- 在“实例管理”页面,选择目标实例,单击实例名称,进入实例的“概览”页面。
- 在左侧导航栏选择“数据库与账号管理”。
- 在“数据库管理”页签下,单击“更多 > 动态脱敏”。
图1 数据库管理
- 在弹出页面中,单击“添加规则”,输入schema、表名称、列字段后选择脱敏格式,单击“保存”。
图2 动态脱敏
- 设置完需要配置动态脱敏的字段后,单击“确定”。
- 准备数据。
- 创建一个数据库,用来存放将要使用的表和数据。
-- 创建一个示例数据库 CREATE DATABASE DemoDDM; GO -- 使用新创建的数据库 USE DemoDDM; GO
- 创建一个表,并指定列的脱敏规则。
-- 创建一个包含敏感信息的表,并直接应用脱敏规则 CREATE TABLE Employees ( Id INT IDENTITY PRIMARY KEY, Name VARCHAR(50), SSN VARCHAR(11) MASKED WITH (FUNCTION = 'partial(1, "XXX-XX-", 4)'), CreditCard VARCHAR(19) MASKED WITH (FUNCTION = 'partial(4, "XXXX-XXXX-XXXX-", 4)') ); GO -- 插入一些示例数据 INSERT INTO Employees (Name, SSN, CreditCard) VALUES ('Alice', '123-45-6789', '1234-5678-9012-3456'), ('Bob', '234-56-7890', '9876-5432-1098-7654'); GO
- 验证脱敏效果。
-- 拥有DemoDDM库的db_datareader角色权限,没有数据库db_owner角色权限 SELECT * FROM Employees;
查询结果应如下所示:
| Id | Name | SSN | CreditCard | |----|-------|----------------|-----------------------------| | 1 | Alice | 1XXX-XX-678 | 1234XXXX-XXXX-XXXX- | | 2 | Bob | 2XXX-XX-789 | 9876XXXX-XXXX-XXXX- |
- 创建一个数据库,用来存放将要使用的表和数据。
- 动态数据脱敏的基础使用。
- 修改现有表以应⽤动态数据脱敏。
如果表已经存在,执行2.b使用ALTER TABLE命令为已存在的列添加脱敏规则。
-- 创建一个新的表 CREATE TABLE Customers ( Id INT IDENTITY PRIMARY KEY, Name VARCHAR(50), Email VARCHAR(100), PhoneNumber VARCHAR(15) ); GO -- 插入一些示例数据 INSERT INTO Customers (Name, Email, PhoneNumber) VALUES ('Charlie', 'charlie@example.com', '123-456-7890'), ('Diana', 'diana@example.com', '987-654-3210'); GO
- 为已有表中的列添加脱敏规则。
-- 为 Email 列添加脱敏规则 ALTER TABLE Customers ALTER COLUMN Email ADD MASKED WITH (FUNCTION = 'email()'); GO -- 为 PhoneNumber 列添加脱敏规则 ALTER TABLE Customers ALTER COLUMN PhoneNumber ADD MASKED WITH (FUNCTION = 'partial(5, "XXX-", 0)'); GO
- 执行一个查询,验证脱敏效果。
-- 没有适当权限的用户看到的数据 SELECT * FROM Customers;
查询结果应如下所示:
| Id | Name | Email | PhoneNumber | |----|--------|------------------------------|-----------------| | 1 | Charlie| cXXX@XXXX.com | 123-4XXX- | | 2 | Diana | dXXX@XXXX.com | 987-6XXX- |
- 修改现有表以应⽤动态数据脱敏。
- 关于SQL Server动态数据脱敏函数以及权限的使用方法,请参见函数及权限相关操作。
动态数据脱敏函数的使用示例如下:
- 使用default()函数
-- 为某个列使用 default() 函数 CREATE TABLE SensitiveData ( Id INT IDENTITY PRIMARY KEY, Value VARCHAR(50) MASKED WITH (FUNCTION = 'default()') ); GO -- 插入一些示例数据 INSERT INTO SensitiveData (Value) VALUES ('Confidential Information 1'), ('Confidential Information 2'); GO -- 查询表,查看脱敏效果 SELECT * FROM SensitiveData;
查询结果应如下所示:
| Id | Value | |----|---------------------------| | 1 | xxxx | | 2 | xxxx |
- 使用random()函数
-- 为某个列使用 random() 函数 CREATE TABLE Accounts ( Id INT IDENTITY PRIMARY KEY, Balance DECIMAL(10, 2) MASKED WITH (FUNCTION = 'random(1000, 5000)') ); GO -- 插入一些示例数据 INSERT INTO Accounts (Balance) VALUES (1234.56), (4567.89); GO -- 查询表,查看脱敏效果 SELECT * FROM Accounts;
查询结果应如下所示:
| Id | Balance | |----|---------| | 1 | 3456.78 | | 2 | 1234.56 |