文档主页
MySQL 9.0 参考手册
相关文档 下载本手册
PDF (US Ltr) - 40.0Mb
PDF (A4) - 40.1Mb
手册页 (TGZ) - 258.2Kb
手册页 (Zip) - 365.3Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 9.0 参考手册  /  ...  /  使用 MySQL 企业版数据脱敏和去标识组件

8.5.2.2 使用 MySQL 企业版数据脱敏和去标识组件

在使用 MySQL 企业版数据脱敏和去标识之前,请按照 第 8.5.2.1 节“MySQL 企业版数据脱敏和去标识组件安装” 中提供的说明进行安装。

要在应用程序中使用 MySQL 企业版数据脱敏和去标识,请调用适合您要执行的操作的函数。有关函数的详细描述,请参见 第 8.5.2.4 节“MySQL 企业版数据脱敏和去标识组件功能描述”。本节演示如何使用这些函数来执行一些代表性任务。首先概述了可用的函数,然后给出了一些在实际环境中如何使用这些函数的示例

脱敏数据以去除识别特征

MySQL 提供通用的脱敏组件函数来脱敏任意字符串,以及专门的脱敏函数来脱敏特定类型的值。

通用脱敏组件函数

mask_inner()mask_outer() 是通用函数,它们根据字符串中的位置来脱敏任意字符串的部分。这两个函数都支持以任何字符集编码的输入字符串

  • mask_inner() 掩盖其字符串参数的内部,留下末端未掩盖。其他参数指定未掩盖末端的大小。

    mysql> SELECT mask_inner('This is a string', 5, 1);
    +--------------------------------------+
    | mask_inner('This is a string', 5, 1) |
    +--------------------------------------+
    | This XXXXXXXXXXg                     |
    +--------------------------------------+
    mysql> SELECT mask_inner('This is a string', 1, 5);
    +--------------------------------------+
    | mask_inner('This is a string', 1, 5) |
    +--------------------------------------+
    | TXXXXXXXXXXtring                     |
    +--------------------------------------+
    mysql> SELECT mask_inner("かすみがうら市", 3, 1);
    +----------------------------------+
    | mask_inner("かすみがうら市", 3, 1) |
    +----------------------------------+
    | かすみXXX市                       |
    +----------------------------------+
    mysql> SELECT mask_inner("かすみがうら市", 1, 3);
    +----------------------------------+
    | mask_inner("かすみがうら市", 1, 3) |
    +----------------------------------+
    | かXXXうら市                       |
    +----------------------------------+
  • mask_outer() 做相反的事情,掩盖其字符串参数的末端,留下内部未掩盖。其他参数指定掩盖末端的大小。

    mysql> SELECT mask_outer('This is a string', 5, 1);
    +--------------------------------------+
    | mask_outer('This is a string', 5, 1) |
    +--------------------------------------+
    | XXXXXis a strinX                     |
    +--------------------------------------+
    mysql> SELECT mask_outer('This is a string', 1, 5);
    +--------------------------------------+
    | mask_outer('This is a string', 1, 5) |
    +--------------------------------------+
    | Xhis is a sXXXXX                     |
    +--------------------------------------+

默认情况下,mask_inner()mask_outer() 使用 'X' 作为掩盖字符,但允许可选的掩盖字符参数

mysql> SELECT mask_inner('This is a string', 5, 1, '*');
+-------------------------------------------+
| mask_inner('This is a string', 5, 1, '*') |
+-------------------------------------------+
| This **********g                          |
+-------------------------------------------+
mysql> SELECT mask_inner("かすみがうら市", 2, 2, "#");
+---------------------------------------+
| mask_inner("かすみがうら市", 2, 2, "#") |
+---------------------------------------+
| かす###ら市                            |
+---------------------------------------+
专门的脱敏组件函数

其他脱敏函数期望一个字符串参数,该参数表示特定类型的值,并对其进行脱敏以去除识别特征。

注意

这里的示例使用返回适当类型值的随机值生成函数来提供函数参数。有关生成函数的更多信息,请参见 使用特定特征生成随机数据

付款卡主账号脱敏。  脱敏函数提供严格和宽松的主账号脱敏。

  • mask_pan() 掩盖除了最后四位数字之外的所有数字

    mysql> SELECT mask_pan(gen_rnd_pan());
    +-------------------------+
    | mask_pan(gen_rnd_pan()) |
    +-------------------------+
    | XXXXXXXXXXXX2461        |
    +-------------------------+
  • mask_pan_relaxed() 类似,但不掩盖指示付款卡发卡机构的未掩盖的前六位数字

    mysql> SELECT mask_pan_relaxed(gen_rnd_pan());
    +---------------------------------+
    | mask_pan_relaxed(gen_rnd_pan()) |
    +---------------------------------+
    | 770630XXXXXX0807                |
    +---------------------------------+

国际银行帐号脱敏。  mask_iban() 掩盖除了前两位字母(表示国家)之外的所有字母

mysql> SELECT mask_iban(gen_rnd_iban());
+---------------------------+
| mask_iban(gen_rnd_iban()) |
+---------------------------+
| ZZ** **** **** ****       |
+---------------------------+

通用唯一标识符脱敏。  mask_uuid() 掩盖所有有意义的字符

mysql> SELECT mask_uuid(gen_rnd_uuid());
+--------------------------------------+
| mask_uuid(gen_rnd_uuid())            |
+--------------------------------------+
| ********-****-****-****-************ |
+--------------------------------------+

美国社会安全号码掩码。  mask_ssn() 掩盖除最后四位数字以外的所有数字

mysql> SELECT mask_ssn(gen_rnd_ssn());
+-------------------------+
| mask_ssn(gen_rnd_ssn()) |
+-------------------------+
| ***-**-1723             |
+-------------------------+

加拿大社会保险号码掩码。  mask_canada_sin() 掩盖号码中的有意义数字

mysql> SELECT mask_canada_sin(gen_rnd_canada_sin());
+---------------------------------------+
| mask_canada_sin(gen_rnd_canada_sin()) |
+---------------------------------------+
| XXX-XXX-XXX                           |
+---------------------------------------+

英国国民保险号码掩码。  mask_uk_nin() 掩盖除前两位数字以外的所有数字

mysql> SELECT mask_uk_nin(gen_rnd_uk_nin());
+-------------------------------+
| mask_uk_nin(gen_rnd_uk_nin()) |
+-------------------------------+
| ZH*******                     |
+-------------------------------+
使用特定特征生成随机数据

几个组件函数生成随机值。这些值可用于测试、模拟等。

gen_range() 返回从给定范围内选择的随机整数

mysql> SELECT gen_range(1, 10);
+------------------+
| gen_range(1, 10) |
+------------------+
|                6 |
+------------------+

gen_rnd_canada_sin() 返回从未用于合法号码的范围内选择的随机号码

mysql> SELECT gen_rnd_canada_sin();
+----------------------+
| gen_rnd_canada_sin() |
+----------------------+

(gen_rnd_canada_sin() 函数结果未显示,因为其返回值仅应用于测试目的,而不应用于发布。无法保证该号码未分配给合法的加拿大 SIN。)

gen_rnd_email() 返回一个随机电子邮件地址,该地址在指定的域中为姓名和姓氏部分指定了数字数量,以下示例中为 mynet.com

mysql> SELECT gen_rnd_email(6, 8, 'mynet.com');
+------------------------------+
| gen_rnd_email(6, 8, 'mynet') |
+------------------------------+
| [email protected]    |
+------------------------------+

gen_rnd_iban() 返回从未用于合法号码的范围内选择的号码

mysql> SELECT gen_rnd_iban('XO', 24);
+-------------------------------+
| gen_rnd_iban('XO', 24)        |
+-------------------------------+
| XO25 SL7A PGQR B9NN 6IVB RFE8 |
+-------------------------------+

gen_rnd_pan() 返回随机的支付卡主账户号码

mysql> SELECT gen_rnd_pan();

(gen_rnd_pan() 函数结果未显示,因为其返回值仅应用于测试目的,而不应用于发布。无法保证该号码未分配给合法的支付帐户。)

gen_rnd_ssn() 返回一个随机的美国社会安全号码,其第一部分和第二部分分别从未用于合法号码的范围内选择

mysql> SELECT gen_rnd_ssn();
+---------------+
| gen_rnd_ssn() |
+---------------+
| 912-45-1615   |
+---------------+

gen_rnd_uk_nin() 返回从未用于合法号码的范围内选择的号码

mysql> SELECT gen_rnd_uk_nin();
+------------------+
| gen_rnd_uk_nin() |
+------------------+

(gen_rnd_uk_nin() 函数结果未显示,因为其返回值仅应用于测试目的,而不应用于发布。无法保证该号码未分配给合法的 NIN。)

gen_rnd_us_phone() 返回一个随机的美国电话号码,该电话号码位于 555 区号内,未用于合法号码

mysql> SELECT gen_rnd_us_phone();
+--------------------+
| gen_rnd_us_phone() |
+--------------------+
| 1-555-747-5627     |
+--------------------+

gen_rnd_uuid() 返回从未用于合法标识符的范围内选择的号码

mysql> SELECT gen_rnd_uuid();
+--------------------------------------+
| gen_rnd_uuid()                       |
+--------------------------------------+
| 68946384-6880-3150-6889-928076732539 |
+--------------------------------------+
使用字典生成随机数据

MySQL 企业数据掩码和去标识化允许使用字典作为称为terms 的随机值的来源。要使用字典,必须首先将其添加到 masking_dictionaries 系统表中并赋予一个名称。这些字典从表中读取并在组件初始化期间(在服务器启动时)加载到缓存中。然后,可以向字典中添加、删除和选择项,并将其用作随机值或作为其他值的替代值。

注意

始终使用字典管理功能编辑字典,而不是直接修改表。如果您手动操作该表,字典缓存将与该表不一致。

有效的 masking_dictionaries 表具有以下特征

  • 管理员在 mysql 模式中创建了 masking_dictionaries 系统表,如下所示

    CREATE TABLE IF NOT EXISTS
    masking_dictionaries(
        Dictionary VARCHAR(256) NOT NULL,
        Term VARCHAR(256) NOT NULL,
        UNIQUE INDEX dictionary_term_idx (Dictionary, Term),
        INDEX dictionary_idx (Dictionary)
    ) ENGINE = InnoDB DEFAULT CHARSET=utf8mb4;
  • 需要 MASKING_DICTIONARY_ADMIN 权限才能添加和删除项,或删除整个字典。

  • 该表可能包含多个字典及其项。

  • 任何用户帐户都可以查看字典。如果查询次数足够多,则可以检索字典中的所有项。避免向字典表中添加敏感数据。

假设名为 DE_cities 的字典包含德国的以下城市名称

Berlin
Munich
Bremen

使用 masking_dictionary_term_add() 为字典名称和一个项分配值

mysql> SELECT masking_dictionary_term_add('DE_Cities', 'Berlin');
+----------------------------------------------------+
| masking_dictionary_term_add('DE_Cities', 'Berlin') |
+----------------------------------------------------+
|                                                  1 |
+----------------------------------------------------+
mysql> SELECT masking_dictionary_term_add('DE_Cities', 'Munich');
+----------------------------------------------------+
| masking_dictionary_term_add('DE_Cities', 'Munich') |
+----------------------------------------------------+
|                                                  1 |
+----------------------------------------------------+
mysql> SELECT masking_dictionary_term_add('DE_Cities', 'Bremen');
+----------------------------------------------------+
| masking_dictionary_term_add('DE_Cities', 'Bremen') |
+----------------------------------------------------+
|                                                  1 |
+----------------------------------------------------+

还假设名为 US_Cities 的字典包含美国以下城市名称

Houston
Phoenix
Detroit
mysql> SELECT masking_dictionary_term_add('US_Cities', 'Houston');
+-----------------------------------------------------+
| masking_dictionary_term_add('US_Cities', 'Houston') |
+-----------------------------------------------------+
|                                                   1 |
+-----------------------------------------------------+
mysql> SELECT masking_dictionary_term_add('US_Cities', 'Phoenix');
+-----------------------------------------------------+
| masking_dictionary_term_add('US_Cities', 'Phoenix') |
+-----------------------------------------------------+
|                                                   1 |
+-----------------------------------------------------+
mysql> SELECT masking_dictionary_term_add('US_Cities', 'Detroit');
+-----------------------------------------------------+  
| masking_dictionary_term_add('US_Cities', 'Detroit') |
+-----------------------------------------------------+
|                                                   1 |
+-----------------------------------------------------+

要从字典中选择一个随机项,请使用 gen_dictionary()

mysql> SELECT gen_dictionary('DE_Cities');
+-----------------------------+
| gen_dictionary('DE_Cities') |
+-----------------------------+
| Berlin                      |
+-----------------------------+
mysql> SELECT gen_dictionary('US_Cities');
+-----------------------------+
| gen_dictionary('US_Cities') |
+-----------------------------+
| Phoenix                     |
+-----------------------------+

要从多个字典中选择一个随机项,请随机选择一个字典,然后从中选择一个项

mysql> SELECT gen_dictionary(ELT(gen_range(1,2), 'DE_Cities', 'US_Cities'));
+---------------------------------------------------------------+
| gen_dictionary(ELT(gen_range(1,2), 'DE_Cities', 'US_Cities')) |
+---------------------------------------------------------------+
| Detroit                                                       |
+---------------------------------------------------------------+
mysql> SELECT gen_dictionary(ELT(gen_range(1,2), 'DE_Cities', 'US_Cities'));
+---------------------------------------------------------------+
| gen_dictionary(ELT(gen_range(1,2), 'DE_Cities', 'US_Cities')) |
+---------------------------------------------------------------+
| Bremen                                                        |
+---------------------------------------------------------------+

gen_blocklist() 函数允许用来自另一个字典的项替换来自一个字典的项,这会通过替换来影响掩码。其参数是要替换的项、该项所在的字典以及要从中选择替换项的字典。例如,要将美国城市替换为德国城市,反之亦然,请使用 gen_blocklist(),如下所示

mysql> SELECT gen_blocklist('Munich', 'DE_Cities', 'US_Cities');
+---------------------------------------------------+
| gen_blocklist('Munich', 'DE_Cities', 'US_Cities') |
+---------------------------------------------------+
| Houston                                           |
+---------------------------------------------------+
mysql> SELECT gen_blocklist('El Paso', 'US_Cities', 'DE_Cities');
+----------------------------------------------------+
| gen_blocklist('El Paso', 'US_Cities', 'DE_Cities') |
+----------------------------------------------------+
| Bremen                                             |
+----------------------------------------------------+

如果要替换的项不在第一个字典中,gen_blocklist() 将按原样返回它

mysql> SELECT gen_blocklist('Moscow', 'DE_Cities', 'US_Cities');
+---------------------------------------------------+
| gen_blocklist('Moscow', 'DE_Cities', 'US_Cities') |
+---------------------------------------------------+
| Moscow                                            |
+---------------------------------------------------+
使用掩码数据进行客户识别

在客户服务呼叫中心,一种常见的身份验证技术是要求客户提供其社会安全号码 (SSN) 的最后四位数字。例如,客户可能会说她的名字是 Joanna Bond,她的最后四位 SSN 数字是 0007

假设包含客户记录的 customer 表具有以下列

  • id:客户 ID 号码。

  • first_name:客户名。

  • last_name:客户姓氏。

  • ssn:客户社会安全号码。

例如,该表可能定义如下

CREATE TABLE customer
(
  id         BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  first_name VARCHAR(40),
  last_name  VARCHAR(40),
  ssn        VARCHAR(11)
);

客户服务代表用来检查客户 SSN 的应用程序可能会执行类似于此的查询

mysql> SELECT id, ssn
mysql> FROM customer
mysql> WHERE first_name = 'Joanna' AND last_name = 'Bond';
+-----+-------------+
| id  | ssn         |
+-----+-------------+
| 786 | 906-39-0007 |
+-----+-------------+

但是,这会将 SSN 公开给客户服务代表,而客户服务代表只需要查看最后四位数字。相反,应用程序可以使用此查询仅显示掩码的 SSN

mysql> SELECT id, mask_ssn(CONVERT(ssn USING binary)) AS masked_ssn
mysql> FROM customer
mysql> WHERE first_name = 'Joanna' AND last_name = 'Bond';
+-----+-------------+
| id  | masked_ssn  |
+-----+-------------+
| 786 | ***-**-0007 |
+-----+-------------+

现在,代表仅看到必要的信息,并且客户隐私得以保护。

为什么 CONVERT() 函数被用作 mask_ssn() 的参数?因为 mask_ssn() 需要长度为 11 的参数。因此,即使 ssn 被定义为 VARCHAR(11),如果 ssn 列具有多字节字符集,它在传递给可加载函数时似乎比 11 字节更长,并返回 NULL 同时记录错误。将值转换为二进制字符串可确保函数看到长度为 11 的参数。

当字符串参数没有单字节字符集时,其他数据掩码函数可能也需要类似的技术。

创建显示掩码数据的视图

如果从表中获取的掩码数据用于多个查询,定义一个生成掩码数据的视图可能会很方便。这样,应用程序就可以从视图中进行选择,而无需在单个查询中执行掩码。

例如,可以针对上一节中的 customer 表定义一个掩码视图,如下所示

CREATE VIEW masked_customer AS
SELECT id, first_name, last_name,
mask_ssn(CONVERT(ssn USING binary)) AS masked_ssn
FROM customer;

然后,查找客户的查询变得更简单,但仍然返回掩码数据

mysql> SELECT id, masked_ssn
mysql> FROM masked_customer
mysql> WHERE first_name = 'Joanna' AND last_name = 'Bond';
+-----+-------------+
| id  | masked_ssn  |
+-----+-------------+
| 786 | ***-**-0007 |
+-----+-------------+