数据动态脱敏

当您期望某些用户只可以查看MaxCompute项目中隐藏关键信息的敏感数据时,您可以开启MaxCompute动态脱敏功能,在数据访问或展示时实时隐藏或替换敏感数据,以防止敏感数据泄露。本文为您介绍如何开启MaxCompute动态脱敏功能,并提供参考示例。

功能介绍

MaxCompute提供数据动态脱敏功能,用于业务开发测试、数据共享、运维等场景中对个人身份信息(PII)等敏感数据以脱敏计算和展示的方式进行保护。脱敏策略支持掩码、散列、字符替换、数值取整、日期取整等脱敏策略,支持与数据保护伞的数据分类分级功能联动,满足用户对身份信息、银行卡号、地址、电话等数据的脱敏需求。

MaxCompute数据脱敏在最靠近数据从存储中读取的环节中实现,确保数据在查询、下载、关联、UDF计算时已经处于脱敏状态,避免敏感数据泄露风险。image

使用限制

  • 支持地域

    该功能目前处于公测阶段,仅华东1(杭州)、华东2(上海)、华北2(北京)、华北3(张家口)、华北6(乌兰察布)、华南1(深圳)、西南1(成都)、中国香港、日本(东京)、马来西亚(吉隆坡)、印度尼西亚(雅加达)、德国(法兰克福)地域支持数据动态脱敏。

  • 支持的驱动版本

    MaxCompute连接方式

    驱动版本

    脱敏功能支持情况

    Java SDK

    0.48.0-public及以上版本

    支持

    odpscmd

    0.47.1及以上版本

    支持

    JDBC

    3.4.3及以上版本

    支持

    MaxFrame

    不限制

    支持

    PyODPS

    不限制

    支持

    Go SDK

    不限制

    支持

  • 内部表

    • MaxCompute内部表支持数据脱敏策略,外部表不支持。

    • 数据脱敏与行级权限功能互斥,已配置脱敏策略的表不支持再配置行级权限策略,反之亦然。

    • 对中文字符使用掩码策略脱敏时,中文字符编码格式必须为UTF-8。

  • 视图

    • 传统的视图支持数据脱敏策略,视图脱敏策略与原脱敏表脱敏策略同步,当原表绑定、解绑脱敏策略时,传统的视图会同步生效。

    • 物化视图依据视图创建时原表的脱敏策略建立对应的脱敏数据视图。当原表继续绑定、解绑脱敏策略时,物化视图维持创建时的脱敏策略不变。

  • 脱敏策略

    当用户访问敏感数据时,如果同时有多条脱敏策略生效,将执行优先级较高的脱敏策略对敏感数据进行脱敏。详情请参见预定义脱敏策略优先级

数据脱敏流程

在数据返回过程中,会检查用户对应的脱敏规则配置情况,如果已经配置了脱敏规则,需要按照规则返回脱敏后的数据,如果没有配置则返回明文。image

脱敏命令

项目开启或关闭数据脱敏功能

脱敏功能开关odps.data.masking.policy.enable为项目空间的Project级属性,只有项目Owner或被赋予项目级别的Super_Administrator和Admin角色的账号可以进行操作,操作详情请参见为用户赋予内置管理角色

  • 项目开启数据脱敏功能。

    setproject odps.data.masking.policy.enable=true;
  • 项目关闭数据脱敏功能。

    setproject odps.data.masking.policy.enable=false;

创建和删除脱敏策略

  • 命令格式

    • 创建脱敏策略。

      CREATE DATA MASKING POLICY [IF NOT EXISTS] <policy_name> 
      TO { USER <user_list> | ROLE <role_list> | default } 
      USING <Predefined Masking Policy>;
    • 删除脱敏策略。

      DROP DATA MASKING POLICY <policy_name>;
  • 参数说明

    参数名称

    是否必填

    描述

    policy_name

    脱敏策略名称。策略名称大小写不敏感,不支持特殊字符,只能包含a~z、A~Z、数字和下划线。建议以字母开头,名称的长度不超过128字节。

    USER | ROLE | default

    三者选其一。

    • USER:对用户脱敏,<user_list>填写待脱敏的用户名称。您可以在MaxCompute中执行list users;命令获取角色信息。

    • ROLE:对角色脱敏,<role_list>填写待脱敏的角色名称。您可以在MaxCompute中执行list roles;命令获取角色信息。

    • default:默认脱敏,用户或角色访问敏感列时如果没有匹配到脱敏策略,那么采用default策略对敏感列进行脱敏。

    Predefined Masking Policy

    预定义的脱敏策略,详情请参见预定义脱敏策略

  • 使用示例

    • 示例1:为用户userA、userB和userC创建MD5哈希脱敏策略。

      CREATE data masking policy IF NOT EXISTS masking_test_001
      TO USER (userA, userB, userC)
      USING MASKED_MD5(0);
    • 示例2:为项目开发角色和运维角色创建MD5哈希脱敏策略。

      CREATE data masking policy IF NOT EXISTS masking_test_001
      TO ROLE (role_project_deploy, role_project_dev)
      USING MASKED_MD5(0);

将脱敏策略应用于敏感数据列

  • 命令格式

    --将脱敏策略应用于敏感表的敏感数据列
    APPLY DATA MASKING POLICY <policy_name> BIND TO TABLE <table_name> COLUMN <column_name>;
    
    --为敏感表的敏感数据列取消指定的脱敏策略
    APPLY DATA MASKING POLICY <policy_name> UNBIND FROM TABLE <table_name> COLUMN <column_name>;
    
    --为敏感表的敏感数据列取消全部脱敏策略
    APPLY DATA MASKING POLICY UNBIND ALL FROM TABLE <table_name> COLUMN <column_name>;
    
    --为敏感表的全部敏感数据列取消全部脱敏策略
    APPLY DATA MASKING POLICY UNBIND ALL FROM TABLE <table_name>;
  • 参数说明

    参数名称

    是否必填

    描述

    policy_name

    脱敏策略名称。

    table_name

    表名称。包含敏感数据的表。

    column_name

    列名称。包含敏感数据的列。

查看脱敏策略

  • 命令格式

    --查看脱敏策略的创建信息
    DESC DATA MASKING POLICY <policy_name>;
    
    --查看表的扩展信息,包含敏感数据列的信息应用的脱敏策略信息
    DESC EXTENDED <table_name>;
    
    --显示当前Project下所有的脱敏策略名称
    LIST DATA MASKING POLICY;
    
    --显示与指定用户绑定的脱敏策略名称
    LIST DATA MASKING POLICY TO USER <user_name>;
    
    --显示与指定角色绑定的脱敏策略名称
    LIST DATA MASKING POLICY TO ROLE <role_name>;
    
    --显示与指定表绑定的所有脱敏策略名称
    LIST DATA MASKING POLICY ON <table_name>;
    
    --显示与指定表指定列绑定的所有脱敏策略名称
    LIST DATA MASKING POLICY ON <table_name> TO COLUMN <column_name>;
  • 参数说明

    参数名称

    是否必填

    描述

    policy_name

    脱敏策略名称。

    table_name

    表名称。包含敏感数据的表。

    column_name

    列名称。包含敏感数据的列。

    user_name

    用户名称。

    role_name

    角色名称。

预定义脱敏策略

预定义脱敏策略包含掩码、散列、字符替换、取整等脱敏策略,您可以根据敏感数据类型选择适用的脱敏策略实现数据保护。

策略类型

策略名称

命令格式

描述

通用

不脱敏

UNMASKED

不脱敏。

支持类型:全部类型。

置空值

MASKED_NULLIFY

置空值,数据脱敏后返回NULL。

  • 支持类型:全部类型。

  • 示例

    --脱敏前,数据类型string
    +------------+
    | col_string |
    +------------+
    | Michael Johnson |
    +------------+
    
    --脱敏策略
    MASKED_NULLIFY
    
    --脱敏后
    +------------+
    | col_string | 
    +------------+
    | NULL       | 
    +------------+

赋默认值

MASKED_DV

赋默认值,每种数据类型的默认值请参见赋默认值脱敏策略(MASKED_DV)的赋值参考

  • 支持类型:全部类型。

  • 示例

    --脱敏前,数据类型timestamp
    +---------------+
    | col_timestamp |
    +---------------+
    | 2024-05-01 11:12:13 |
    +---------------+
    --脱敏策略
    MASKED_DV
    --脱敏后,Project时区默认是中国的东八区
    +---------------+
    | col_timestamp | 
    +---------------+
    | 1970-01-01 08:00:00 | 
    +---------------+

只保留年份

MASKED_DATE_YEAR

只保留时间的年份数值,非年份数值设置为1月1日00:00(UTC时间)。

  • 支持类型:DATE、DATETIME、TIMESTAMP_NTZ、TIMESTAMP。

  • 示例

    --脱敏前,数据类型timestamp
    +---------------+
    | col_timestamp |
    +---------------+
    | 2024-05-01 11:12:13 |
    +---------------+
    --脱敏策略
    MASKED_DATE_YEAR
    --脱敏后,Project时区默认是中国的东八区
    +---------------+
    | col_timestamp | 
    +---------------+
    | 2024-01-01 08:00:00 | 
    +---------------+

取整

MASKED_POINT_RESERVE(<num>)

取整,保留小数点后0~5位小数。

  • num:保留小数点后的位数,num取值为[0, 5]的整数。

  • 支持类型:DECIMAL、FLOAT、DOUBLE。

  • 示例

    --脱敏前,数据类型float
    +-----------+
    | col_float |
    +-----------+
    | 1.12345   |
    +-----------+
    --脱敏策略,保留2位小数
    MASKED_POINT_RESERVE(2)
    --脱敏后
    +------------+
    | col_float  | 
    +------------+
    | 1.12       | 
    +------------+

掩码

字符串头尾部分掩码

MASKED_STRING_MASKED_BA(<before>, <after>)

字符串头尾部分用*掩码,中间部分用明文显示。

  • before:字符串起始部分将被*替换,掩码长度由参数before指定,before取值为大于等于0的整数。当before的值为0时,前部不进行掩码处理。

  • after:字符串的尾部将被*替换,掩码长度由参数after指定,after取值为大于等于0的整数。

  • 支持类型:STRING、VARCHAR、CHAR、BINARY。

  • 示例

    --脱敏前,数据类型string
    +------------+
    | col_string |
    +------------+
    | Michael Johnson |
    +------------+
    --脱敏策略,前3位,后3位字符用*号代替,中间位明文显示
    MASKED_STRING_MASKED_BA(3, 3)
    --脱敏后
    +------------+
    | col_string | 
    +------------+
    | ***hael John*** | 
    +------------+

字符串中间部分掩码

MASKED_STRING_UNMASKED_BA(<before>, <after>)

字符串头尾部分用明文,中间部分用*掩码。

  • before:字符串头部明文的字符长度,before取值为大于等于0的整数。

  • after:字符串尾部明文的字符长度,after取值为大于等于0的整数。

  • 支持类型:STRING、VARCHAR、CHAR、BINARY。

  • 示例

    --脱敏前,数据类型string
    +------------+
    | col_string |
    +------------+
    | Michael Johnson |
    +------------+
    --脱敏策略,保留前1位,后1位明文显示
    MASKED_STRING_UNMASKED_BA(1, 1)
    --脱敏后
    +------------+
    | col_string | 
    +------------+
    | M*************n | 
    +------------+

散列

SHA256散列

MASKED_SHA256(<salt>)

SHA256散列算法脱敏。

  • salt:盐值,num取值为0~9的整数。

  • 支持类型:STRING、VARCHAR、CHAR、BINARY。

  • 示例

    --脱敏前,数据类型string
    +------------+
    | col_string | 
    +------------+
    | 4562-1234-5678-9123 | 
    +------------+
    --脱敏策略
    MASKED_SHA256(0)
    --脱敏后
    +------------+
    | col_string | 
    +------------+
    | zwGMB1aCF1t705EfcwdDorql4MZb46XBqQJw/2RVx8U= | 
    +------------+

SHA512散列

MASKED_SHA512(<salt>)

SHA512散列算法脱敏。

  • salt:盐值,num取值为0~9的整数。

  • 支持类型:STRING、VARCHAR、CHAR、BINARY。

  • 示例

    --脱敏前,数据类型string
    +------------+
    | col_string | 
    +------------+
    | 4562-1234-5678-9123 | 
    +------------+
    --脱敏策略
    MASKED_SHA512(0)
    --脱敏后
    +------------+
    | col_string | 
    +------------+
    | 3PPywfEIp08WuTUI8FZCCfdVuRu68wZTVwWWVAf4pboACUnH6w9kFMLpl2AARaGW/mvWvg26p0EIqmE0fAEiuA== | 
    +------------+

MD5散列

MASKED_MD5(<salt>)

MD5散列算法脱敏。

  • salt:盐值,num取值为0~9的整数。

  • 支持类型:STRING、VARCHAR、CHAR、BINARY。

  • 示例

    --脱敏前,数据类型string
    +------------+
    | col_string | 
    +------------+
    | 4562-1234-5678-9123 | 
    +------------+
    --脱敏策略
    MASKED_MD5(0)
    --脱敏后
    +------------+
    | col_string | 
    +------------+
    | mK/o08tew5g7S3XV/BkFfw== | 
    +------------+

SM3散列

MASKED_SM3(<salt>)

SM3散列算法脱敏。

  • salt:盐值,num取值为0~9的整数。

  • 支持类型:STRING、VARCHAR、CHAR、BINARY。

  • 示例

    --脱敏前,数据类型string
    +------------+
    | col_string | 
    +------------+
    | 4562-1234-5678-9123 | 
    +------------+
    --脱敏策略
    MASKED_SM3(0)
    --脱敏后
    +------------+
    | col_string | 
    +------------+
    | Q2TfwUh4B8QQH8jPL6DfdoGysx/CXBxn2T14dDwQtQw= | 
    +------------+

字符替换

随机字符替换

MASKED_REPLACE_RANDOM(<position>)

用随机字符替换数据,替换后字符串长度不变,随机值包括数字和英文字母。

  • position:字符替换位置,取值为整数。

    • position = 0:数据全部用随机值替换。

    • position > 0:数据的前position位用随机值替换。

    • position < 0:数据的后position位用随机值替换 。

  • 支持类型:STRING、VARCHAR、CHAR、BINARY。

  • 示例

    --脱敏前,数据类型string
    +------------+
    | col_string |
    +------------+
    | Michael Johnson |
    +------------+
    --脱敏策略,字符串前7位用随机字符替换
    MASKED_REPLACE_RANDOM(7)
    --脱敏后
    +------------+
    | col_string | 
    +------------+
    | 4DlJQxi Johnson | 
    +------------+

头尾随机字符替换

MASKED_REPLACE_RANDOM_BA(<before>, <after>)

用随机字符替换数据的头尾部分,替换后字符串长度不变,随机值包括数字和英文字母。

  • before:数据起始部分将被随机字符替换,替换长度由参数before指定,before取值为大于等于0的整数。当before的值为0时,前部不进行替换。

  • after:数据的尾部将被随机字符替换,替换长度由参数after指定,after取值为大于等于0的整数。

  • 支持类型:STRING、VARCHAR、CHAR、BINARY。

  • 示例

    --脱敏前,数据类型string
    +------------+
    | col_string |
    +------------+
    | Michael Johnson |
    +------------+
    --脱敏策略,字符串前4位和后4位用随机字符替换
    MASKED_REPLACE_RANDOM_BA(4,4)
    --脱敏后
    +------------+
    | col_string | 
    +------------+
    | r0xEael JohnWNr | 
    +------------+

固定字符替换

MASKED_REPLACE_FIXED(<position>, <fixed_string>)

  • 用固定字符串替换数据。

  • position:字符替换位置,取值为整数。

    • position = 0:数据全部用fixed_string固定字符串替换。

    • position > 0:数据的前position位用fixed_string替换。

    • position < 0:数据的后-position位用fixed_string替换。

  • fixed_string:固定字符串,固定字符串长度小于等于100,固定字符串中不能包含空格。

  • 支持类型:STRING、VARCHAR、CHAR、BINARY。

  • 示例

    --脱敏前,数据类型string
    +------------+
    | col_string |
    +------------+
    | Michael Johnson |
    +------------+
    --脱敏策略,字符串前7位用固定字符串"Oli"替换
    MASKED_REPLACE_FIXED(7, "Oli")
    --脱敏后
    +------------+
    | col_string | 
    +------------+
    | Oli Johnson | 
    +------------+

使用示例

个人敏感信息脱敏

此处以个人敏感信息为例,为您展示如何配置敏感策略,并对敏感信息进行脱敏。

  1. 数据准备。

    创建个人敏感信息表,并插入敏感数据。

    -- 创建敏感信息表
    CREATE TABLE if NOT EXISTS personal_info (
      id bigint COMMENT '用户唯一标识ID',
      name string COMMENT '用户姓名',
      age int COMMENT '用户年龄',
      gender string COMMENT '用户性别',
      height float COMMENT '用户身高',
      birthday date COMMENT '用户生日',
      phone_number string COMMENT '用户电话号码',
      email string COMMENT '用户电子邮箱',
      address string COMMENT '用户地址',
      salary decimal(18, 2) COMMENT '用户薪水',
      create_time timestamp COMMENT '用户信息创建时间',
      update_time timestamp COMMENT '用户信息更新时间',
      is_deleted boolean COMMENT '用户信息是否被删除的标志位'
    );
    -- 插入敏感数据
    INSERT INTO personal_info VALUES
        (1, '张三', 18, '男', 178.56, '1990-01-01', '13800000000', 'zhangsan@example.com', '北京市海淀区', 5000.00, '2023-04-19 11:32:00', '2023-04-19 11:32:00', false),
        (2, '李四', 20, '女', 162.70, '1992-02-02', '13900000000', 'lisi@example.com', '上海市浦东新区', 6000.00, '2023-04-19 11:32:00', '2023-04-19 11:32:00',false),
        (3, '王五', 22, '男', 185.21, '1994-03-03', '14000000000', 'wangwu@example.com', '深圳市南山区', 7000.00, '2023-04-19 11:32:00', '2023-04-19 11:32:00', false);
  2. 配置脱敏策略。

    • 姓名只保留第1个字,其他字符用*代替。

      CREATE data masking policy IF NOT EXISTS masking_name
      TO USER (RAM$xxx@test.aliyunid.com:xxx)
      USING MASKED_STRING_UNMASKED_BA(1, 0);
      
      apply data masking policy masking_name bind TO
      TABLE personal_info COLUMN name;
    • 身高字段取整。

      CREATE data masking policy IF NOT EXISTS masking_height
      TO USER (RAM$xxx@test.aliyunid.com:xxx)
      USING MASKED_POINT_RESERVE(0);
      
      apply data masking policy masking_height bind TO
      TABLE personal_info COLUMN height;
    • 生日只保留年份。

      CREATE data masking policy IF NOT EXISTS masking_birthday
      TO USER (RAM$xxx@test.aliyunid.com:xxx)
      USING MASKED_DATE_YEAR;
      
      apply data masking policy masking_birthday bind TO
      TABLE personal_info COLUMN birthday;
    • 默认用户使用SM3算法哈希电话号码。

      CREATE DATA MASKING POLICY default_sm3
      TO DEFAULT
      USING MASKED_SM3(0);
      
      apply data masking policy default_sm3 bind TO
      TABLE personal_info COLUMN phone_number;
  3. 使用被脱敏账号,查询脱敏后的数据。

    SELECT id, name, height, birthday, phone_number FROM personal_info;
    
    -- 脱敏前
    +------------+------+--------+----------+--------------+
    | id         | name | height | birthday | phone_number |
    +------------+------+--------+----------+--------------+
    | 1          | 张三 | 178.56 | 1990-01-01 | 13800000000  |
    | 2          | 李四 | 162.7  | 1992-02-02 | 13900000000  |
    | 3          | 王五 | 185.21 | 1994-03-03 | 14000000000  |
    +------------+------+--------+----------+--------------+
    
    -- 脱敏后
    +------------+------------+------------+------------+--------------+
    | id         | name       | height     | birthday   | phone_number | 
    +------------+------------+------------+------------+--------------+
    | 1          | 张*        | 179.0      | 1990-01-01 | lvYJaH4ElL2ilpQx/8tfMUw7xP22yblIgmfWp0/msUQ= | 
    | 2          | 李*        | 163.0      | 1992-01-01 | 9fFWacNSwCRZLAjMHqunlfwkqhTbP2ubuDOeOSh4N1c= | 
    | 3          | 王*        | 185.0      | 1994-01-01 | k/0JoQCSarJg9ATJ5tyVnhQf1jIBxHXRbB+cvUm4OmE= | 
    +------------+------------+------------+------------+--------------+

默认对所有用户和角色脱敏

下述实例为您展示当用户或角色同时命中多种敏感策略时,优先级较高的敏感策略将生效。

对默认用户采用MASKED_SHA256(5)的masking策略。

CREATE DATA MASKING POLICY  default_hash_policy
TO DEFAULT
USING MASKED_SHA256(5);

对特殊用户A,B采用UNMASKED的策略。

CREATE DATA MASKING POLICY  ab_unmask_policy
TO USER (A, B)
USING UNMASKED;

结果:用户A,B可以访问明文数据,其他用户只能访问SHA256散列脱敏的数据。

说明

A,B用户命中MASKED_SHA256(5),UNMASKED策略,因此执行优先级较高的脱敏策略UNMASKED(详情请参见预定义脱敏策略优先级)。其他用户命中MASKED_SHA256(5)策略。

附录

预定义脱敏策略优先级

当用户访问敏感数据时有多条脱敏策略生效时,将执行较高优先级的脱敏策略对敏感数据进行脱敏。

例如用户A访问列col_string同时匹配到2条脱敏策略,分别是优先级3级MASKED_REPLACE_RANDOM(3)和优先级4级MASKED_SM3,系统将执行较高优先级的脱敏策略即MASKED_REPLACE_RANDOM(3),用户A将看到随机字符替换的脱敏结果。

优先级

预定义脱敏策略

0(高)

UNMASKED

1

MASKED_POINT_RESERVE(num)

2

MASKED_DATE_YEAR

3

MASKED_STRING_MASKED_BA(before, after)

MASKED_STRING_UNMASKED_BA(before, after)

MASKED_REPLACE_RANDOM(position)

MASKED_REPLACE_RANDOM_BA(before, after)

MASKED_REPLACE_FIXED(position)

4

MASKED_SHA256

MASKED_SHA512

MASKED_MD5

MASKED_SM3

5

MASKED_DV

6(低)

MASKED_NULLIFY

赋默认值脱敏策略(MASKED_DV)的赋值参考

数据类型

默认值

bigint

0

double

0.0

decimal

0

string

""

datetime

DATETIME'1970-01-01 00:00:00'(UTC时间)

boolean

false

tinyint

0

smallint

0

int

0

binary

''

float

0.0

double

0.0

decimal

0

varchar(n)

""

char(n)

" " (填充n个空格)

date

DATE'1970-01-01'

timestamp

TIMESTAMP'1970-01-01 00:00:00'(UTC时间)

timestamp_ntz

TIMESTAMP'1970-01-01 00:00:00'(UTC时间)

array

{子类型的默认值}

map

{key:value} (key, value分别对应子类型的默认值)

json

""

struct

(子类型的默认值)