计划和实现动态掩码
Azure SQL 数据库、Azure SQL 托管实例和 Azure Synapse Analytics 支持动态数据掩码。 动态数据掩码功能通过对非特权用户屏蔽敏感数据来限制此类数据的泄漏。
动态数据掩码使客户能够指定在对应用层所产生影响最小的前提下可以透露的敏感数据量,从而帮助防止敏感数据遭到未经授权的访问。 它是一项基于策略的安全功能,可以隐藏对指定数据库字段进行查询时获得的结果集中的敏感数据,而不会更改数据库中的数据。
例如,呼叫中心的服务代表可能通过确认呼叫方电子邮件的几个字符来对其进行识别,但是完整的电子邮件地址不应泄露给服务代表。 掩码规则可定义为对任何查询的结果集中的所有电子邮件地址进行掩蔽。 另举一例:在需要进行故障排除时,开发人员可通过定义适当的数据掩码来保护个人数据,因此可在不违反符合性法规的情况下,对生产环境进行查询。
动态数据掩码基础知识
你将通过在 SQL 数据库配置窗格中的“安全性”下选择“动态数据掩码”边栏选项卡,在 Azure 门户中设置动态数据掩码策略。
动态数据掩码策略
- 免屏蔽的 SQL 用户 - 一组可在 SQL 查询结果中获取非掩码数据的 SQL 用户或 Microsoft Entra ID 标识。 始终不会对拥有管理员权限的用户进行掩码,这些用户可以查看没有任何掩码的原始数据。
- 掩码规则 - 一组规则,定义要掩码的指定字段,以及使用的掩码函数。 可以使用数据库架构名称、表名称和列名称定义指定的字段。
- 掩码函数 - 一组方法,用于控制不同情况下的数据透露。
Function | 描述 | 示例 |
---|---|---|
默认值 | 根据指定字段的数据类型进行完全屏蔽。 对于字符串数据类型,如果字段少于 4 个字符(char、nchar、varchar、nvarchar、text、ntext),请使用 XXXX(或更少)。 对于数字数据类型,可使用零值(bigintbitdecimal、 int、 money、 numeric、 smallint、 smallmoney、 tinyint、 float、 real)。 对于日期和时间数据类型,请使用 1900-01-01 00:00:00.0000000(date、datetime2、datetime、datetimeoffset、smalldatetime、time)。 对于二进制数据类型,可使用单字节的 ASCII 值 0(binary、 varbinary、 image)。 |
列定义语法示例:Phone# varchar(12) MASKED WITH (FUNCTION = 'default()') NULL ALTER 语法示例:ALTER COLUMN Gender ADD MASKED WITH (FUNCTION = 'default()') |
电子邮件 | 该屏蔽方法公开电子邮件地址的第一个字母,以及电子邮件地址格式中的常量后缀“.com”。 aXXX@XXXX.com。 | 定义语法示例:Email varchar(100) MASKED WITH (FUNCTION = 'email()') NULL ALTER 语法示例:ALTER COLUMN Email ADD MASKED WITH (FUNCTION = 'email()') |
Random | 一种随机屏蔽函数,适用于任何数字类型,可以在指定范围内使用随机值来屏蔽原始值。 | 定义语法示例:Account_Number bigint MASKED WITH (FUNCTION = 'random([start range], [end range])') ALTER 语法示例:ALTER COLUMN [Month] ADD MASKED WITH (FUNCTION = 'random(1, 12)') |
自定义字符串 | 该屏蔽方法公开第一个和最后一个字母,在中间添加自定义填充字符串。 prefix,[padding],suffix 如果因原始值太短而无法进行完整的掩码,则不会公开部分前缀或后缀。 |
定义语法示例:FirstName varchar(100) MASKED WITH (FUNCTION = 'partial(prefix,[padding],suffix)') NULL ALTER 语法示例:ALTER COLUMN [Phone Number] ADD MASKED WITH (FUNCTION = 'partial(1,"XXXXXXX",0)') 这会将电话号码 555.123.1234 转换为 5XXXXXXX。 其他示例: ALTER COLUMN [Phone Number] ADD MASKED WITH (FUNCTION = 'partial(5,"XXXXXXX",0)') 这会将电话号码 555.123.1234 转换为 555.1XXXXXXX。 |
日期/时间 | 适用于: SQL Server 2022 (16.x) 使用数据类型 datetime、datetime2、date、time、datetimeoffset、smalldatetime 定义的列的掩码方法。 它可以帮助掩盖天的 year => datetime("Y"),month=> datetime("M"),day=>datetime("D"),hour=>datetime("h"),minute=>datetime("m") 或 seconds=>datetime("s") 部分。 |
如何屏蔽 datetime 值的年份的示例: ALTER COLUMN BirthDay ADD MASKED WITH (FUNCTION = 'datetime("Y")') 如何屏蔽 datetime 值的月份的示例: ALTER COLUMN BirthDay ADD MASKED WITH (FUNCTION = 'datetime("M")') 如何屏蔽 datetime 值的分钟的示例: ALTER COLUMN BirthDay ADD MASKED WITH (FUNCTION = 'datetime("m")') |
掩码函数 | 掩码逻辑 |
---|---|
默认 | 根据指定字段的数据类型完全掩码 * 对于字符串数据类型(nchar、ntext、nvarchar),如果字段少于 4 个字符,请使用 XXXX(或更少)。 * 对于数值数据类型(bigint、bit、decimal、int、money、numeric、smallint、smallmoney、tinyint、float、real),将使用零值。 * 对于日期/时间数据类型(date、datetime2、datetime、datetimeoffset、smalldatetime、time),请使用 1900-01-01。 * 对于 sql_variant,将使用当前类型的默认值。 • 对于 XML,使用文档 <masked />。 * 对于特殊数据类型(timestamp、table、HierarchyID、uniqueidentifier、binary、image、varbinary 和空间类型),将使用空值。 |
信用卡 | 此掩码方法公开指定字段的最后四位数,并添加一个信用卡格式的常量字符串作为前缀。 XXXX-XXXX-XXXX-1234 |
电子邮件 | 此掩码方法公开第一个字母并将域替换为 XXX.com,并使用一个电子邮件地址格式的常量字符串作为前缀。 aXX@XXXX.com |
随机数 | 此掩码方法根据选定边界和实际数据类型生成随机数。 如果指定的边界相等,则掩码函数是常数。 |
自定义文本 | 此掩码方法公开第一个和最后一个字符,并在中间添加一个自定义填充字符串。 如果原始字符串短于公开的前缀和后缀,则只使用填充字符串。 前缀 [填充] 后缀 |
建议进行掩码的字段
DDM 建议引擎会将数据库中的某些字段标记为可能的敏感字段,可以考虑对这些字段进行掩码。 在门户的“动态数据掩码”窗格中,会看到针对数据库建议的列。 针对一个或多个列选择“添加掩码”,然后选择相应的掩码函数,并选择“保存”,即可对这些字段应用掩码。
使用 T-SQL 管理动态数据掩码
- 若要创建动态数据掩码,请参阅创建动态数据掩码。
- 若要在现有列上添加或编辑掩码,请参阅在现有列中添加或编辑掩码。
- 若要授予查看未屏蔽数据的权限,请参阅授予查看未屏蔽数据的权限。
- 若要删除动态数据掩码,请参阅删除动态数据掩码。
使用 PowerShell cmdlet 为数据库设置动态数据掩码
数据掩码策略
数据掩码规则
- Get-AzSqlDatabaseDataMaskingRule
- New-AzSqlDatabaseDataMaskingRule
- Remove-AzSqlDatabaseDataMaskingRule
- Set-AzSqlDatabaseDataMaskingRule
使用 REST API 为数据库设置动态数据掩码
你可以使用 REST API 以编程方式管理数据掩码策略和规则。 已发布的 REST API 支持以下操作:
数据掩码策略
数据掩码规则
权限
以下是用于配置动态数据掩码的内置角色:
以下是使用动态数据屏蔽所需的操作:
读/写:
Microsoft.Sql/servers/databases/dataMaskingPolicies/*
读取:
Microsoft.Sql/servers/databases/dataMaskingPolicies/read
写入:
Microsoft.Sql/servers/databases/dataMaskingPolicies/write
若要详细了解在使用带有 T-SQL 命令的动态数据掩码时的权限,请参阅权限
粒度权限示例
通过在数据库的不同级别向未经授权的用户屏蔽敏感数据,来防止对敏感数据进行未经授权的访问并获得控制权。 可以在数据库级别、架构级别、表级别或列级别向任何数据库用户或角色授予或撤销 UNMASK 权限。 结合 Microsoft Entra 身份验证,可以为 Azure 环境中维护的用户、组和应用程序管理 UNMASK 权限。 UNMASK 权限可更精细地控制和限制对数据库中存储的数据进行的未经授权访问,并改进数据安全管理。
创建架构以包含用户表:
CREATE SCHEMA Data; GO
创建具有掩码列的表:
CREATE TABLE Data.Membership ( MemberID INT IDENTITY(1, 1) NOT NULL PRIMARY KEY CLUSTERED, FirstName VARCHAR(100) MASKED WITH (FUNCTION = 'partial(1, "xxxxx", 1)') NULL, LastName VARCHAR(100) NOT NULL, Phone VARCHAR(12) MASKED WITH (FUNCTION = 'default()') NULL, Email VARCHAR(100) MASKED WITH (FUNCTION = 'email()') NOT NULL, DiscountCode SMALLINT MASKED WITH (FUNCTION = 'random(1, 100)') NULL, BirthDay DATETIME MASKED WITH (FUNCTION = 'default()') NULL );
插入示例数据:
INSERT INTO Data.Membership (FirstName, LastName, Phone, Email, DiscountCode, BirthDay) VALUES ('Roberto', 'Tamburello', '555.123.4567', 'RTamburello@contoso.com', 10, '1985-01-25 03:25:05'), ('Janice', 'Galvin', '555.123.4568', 'JGalvin@contoso.com.co', 5, '1990-05-14 11:30:00'), ('Shakti', 'Menon', '555.123.4570', 'SMenon@contoso.net', 50, '2004-02-29 14:20:10'), ('Zheng', 'Mu', '555.123.4569', 'ZMu@contoso.net', 40, '1990-03-01 06:00:00');
创建架构以包含服务表:
CREATE SCHEMA Service; GO
创建具有掩码列的服务表:
CREATE TABLE Service.Feedback ( MemberID INT IDENTITY(1, 1) NOT NULL PRIMARY KEY CLUSTERED, Feedback VARCHAR(100) MASKED WITH (FUNCTION = 'default()') NULL, Rating INT MASKED WITH (FUNCTION = 'default()'), Received_On DATETIME );
插入示例数据:
INSERT INTO Service.Feedback (Feedback, Rating, Received_On) VALUES ('Good', 4, '2022-01-25 11:25:05'), ('Excellent', 5, '2021-12-22 08:10:07'), ('Average', 3, '2021-09-15 09:00:00');
在数据库中创建不同用户:
CREATE USER ServiceAttendant WITHOUT LOGIN; GO CREATE USER ServiceLead WITHOUT LOGIN; GO CREATE USER ServiceManager WITHOUT LOGIN; GO CREATE USER ServiceHead WITHOUT LOGIN; GO
向数据库中的用户授予读取权限:
ALTER ROLE db_datareader ADD MEMBER ServiceAttendant; ALTER ROLE db_datareader ADD MEMBER ServiceLead; ALTER ROLE db_datareader ADD MEMBER ServiceManager; ALTER ROLE db_datareader ADD MEMBER ServiceHead;
向用户授予不同的 UNMASK 权限:
--Grant column level UNMASK permission to ServiceAttendant GRANT UNMASK ON Data.Membership(FirstName) TO ServiceAttendant;
-- Grant table level UNMASK permission to ServiceLead GRANT UNMASK ON Data.Membership TO ServiceLead;
-- Grant schema level UNMASK permission to ServiceManager GRANT UNMASK ON SCHEMA::Data TO ServiceManager; GRANT UNMASK ON SCHEMA::Service TO ServiceManager;
--Grant database level UNMASK permission to ServiceHead; GRANT UNMASK TO ServiceHead;
在用户
ServiceAttendant
的上下文中查询数据:EXECUTE AS USER = 'ServiceAttendant'; SELECT MemberID, FirstName, LastName, Phone, Email, BirthDay FROM Data.Membership; SELECT MemberID, Feedback, Rating FROM Service.Feedback; REVERT;
在用户
ServiceLead
的上下文中查询数据:EXECUTE AS USER = 'ServiceLead'; SELECT MemberID, FirstName, LastName, Phone, Email, BirthDay FROM Data.Membership; SELECT MemberID, Feedback, Rating FROM Service.Feedback; REVERT;
在用户
ServiceManager
的上下文中查询数据:EXECUTE AS USER = 'ServiceManager'; SELECT MemberID, FirstName, LastName, Phone, Email, BirthDay FROM Data.Membership; SELECT MemberID, Feedback, Rating FROM Service.Feedback; REVERT;
在用户
ServiceHead
的上下文中查询数据:EXECUTE AS USER = 'ServiceHead'; SELECT MemberID, FirstName, LastName, Phone, Email, BirthDay FROM Data.Membership; SELECT MemberID, Feedback, Rating FROM Service.Feedback; REVERT;
若要撤销 UNMASK 权限,请使用以下 T-SQL 语句:
REVOKE UNMASK ON Data.Membership(FirstName) FROM ServiceAttendant; REVOKE UNMASK ON Data.Membership FROM ServiceLead; REVOKE UNMASK ON SCHEMA::Data FROM ServiceManager; REVOKE UNMASK ON SCHEMA::Service FROM ServiceManager; REVOKE UNMASK FROM ServiceHead;