Documentation Home
MySQL 8.4 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 39.8Mb
PDF (A4) - 39.9Mb
Man Pages (TGZ) - 257.9Kb
Man Pages (Zip) - 364.9Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 8.4 Reference Manual  /  ...  /  Using the MySQL Enterprise Data Masking and De-Identification Plugin

8.5.3.2 使用 MySQL 企业数据屏蔽和去标识化插件

在使用 MySQL 企业数据屏蔽和去标识化之前,按照第8.5.3.1节,“MySQL 企业数据屏蔽和去标识化插件安装”中的说明进行安装。

要在应用程序中使用 MySQL 企业数据屏蔽和去标识化,调用适用于您想要执行操作的函数。详细函数描述,请见第8.5.3.4节,“MySQL 企业数据屏蔽和去标识化插件函数描述”。该节展示了如何使用函数来完成一些示例任务。首先,介绍可用的函数,然后是函数在实际应用中的示例:

MySQL 提供了通用掩码函数,可以掩码任意字符串,和特殊掩码函数,可以掩码特定的值类型。

General-Purpose Masking Functions

mask_inner()mask_outer() 是通用函数,掩码任意字符串的部分,根据字符串中的位置:

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

    Press CTRL+C to copy
    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 | +--------------------------------------+
  • mask_outer() 做反向操作,掩码其字符串参数的两端,留下内部不掩码。其他参数指定掩码两端的大小。

    Press CTRL+C to copy
    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' 作为掩码字符,但允许可选的掩码字符参数:

Press CTRL+C to copy
mysql> SELECT mask_inner('This is a string', 5, 1, '*'); +-------------------------------------------+ | mask_inner('This is a string', 5, 1, '*') | +-------------------------------------------+ | This **********g | +-------------------------------------------+ mysql> SELECT mask_outer('This is a string', 5, 1, '#'); +-------------------------------------------+ | mask_outer('This is a string', 5, 1, '#') | +-------------------------------------------+ | #####is a strin# | +-------------------------------------------+
Special-Purpose Masking Functions

其他掩码函数预期一个字符串参数,表示特定的值类型,并将其mask以删除识别特征。

Note

以下示例使用随机值生成函数来提供函数参数。关于生成函数的更多信息,请参见根据特定特征生成随机数据

付款卡主账户号掩码  掩码函数提供严格和放松的主账户号掩码。

  • mask_pan() 掩码所有数字,除了最后四位:

    Press CTRL+C to copy
    mysql> SELECT mask_pan(gen_rnd_pan()); +-------------------------+ | mask_pan(gen_rnd_pan()) | +-------------------------+ | XXXXXXXXXXXX2461 | +-------------------------+
  • mask_pan_relaxed() 类似,但不掩码前六位,表示付款卡发行商未掩码:

    Press CTRL+C to copy
    mysql> SELECT mask_pan_relaxed(gen_rnd_pan()); +---------------------------------+ | mask_pan_relaxed(gen_rnd_pan()) | +---------------------------------+ | 770630XXXXXX0807 | +---------------------------------+

美国社会安全号掩码  mask_ssn() 掩码所有数字,除了最后四位:

Press CTRL+C to copy
mysql> SELECT mask_ssn(gen_rnd_ssn()); +-------------------------+ | mask_ssn(gen_rnd_ssn()) | +-------------------------+ | XXX-XX-1723 | +-------------------------+

有多个函数生成随机值。这些值可以用于测试、模拟等。

gen_range() 从给定的范围中返回一个随机整数:

Press CTRL+C to copy
mysql> SELECT gen_range(1, 10); +------------------+ | gen_range(1, 10) | +------------------+ | 6 | +------------------+

gen_rnd_email()example.com 域名中返回一个随机电子邮件地址:

Press CTRL+C to copy
mysql> SELECT gen_rnd_email(); +---------------------------+ | gen_rnd_email() | +---------------------------+ | ayxnq.xmkpvvy@example.com | +---------------------------+

gen_rnd_pan() 返回一个随机支付卡主账户号码:

Press CTRL+C to copy
mysql> SELECT gen_rnd_pan();

(由于 gen_rnd_pan() 函数结果只能用于测试目的,不可用于出版,无法保证该号码未被分配给合法支付账户。)

gen_rnd_ssn() 返回一个随机美国社会安全号码,其中第一个和第二个部分来自未被合法使用的范围:

Press CTRL+C to copy
mysql> SELECT gen_rnd_ssn(); +---------------+ | gen_rnd_ssn() | +---------------+ | 912-45-1615 | +---------------+

gen_rnd_us_phone() 返回一个随机美国电话号码,在 555 区域代码中未被合法使用:

Press CTRL+C to copy
mysql> SELECT gen_rnd_us_phone(); +--------------------+ | gen_rnd_us_phone() | +--------------------+ | 1-555-747-5627 | +--------------------+

MySQL 企业数据掩码和去标识功能使得词典可以用作随机值的来源。要使用词典,首先需要从文件中加载并命名它。每个加载的词典都将成为词典注册表的一部分。然后,可以从已注册的词典中选择项作为随机值或替换其他值。

有效的词典文件具有这些特征:

  • 文件内容是纯文本,一个term占一行。

  • 空白行将被忽略。

  • 文件至少需要包含一个term。

假设有一个名为 de_cities.txt 的文件包含德国城市名称:

Press CTRL+C to copy
Berlin Munich Bremen

也假设有一个名为 us_cities.txt 的文件包含美国城市名称:

Press CTRL+C to copy
Chicago Houston Phoenix El Paso Detroit

假设系统变量 secure_file_priv 设置为 /usr/local/mysql/mysql-files。在这种情况下,复制词典文件到该目录,以便 MySQL 服务器可以访问它们,然后使用 gen_dictionary_load() 将词典加载到词典注册表并赋予名称:

Press CTRL+C to copy
mysql> SELECT gen_dictionary_load('/usr/local/mysql/mysql-files/de_cities.txt', 'DE_Cities'); +--------------------------------------------------------------------------------+ | gen_dictionary_load('/usr/local/mysql/mysql-files/de_cities.txt', 'DE_Cities') | +--------------------------------------------------------------------------------+ | Dictionary load success | +--------------------------------------------------------------------------------+ mysql> SELECT gen_dictionary_load('/usr/local/mysql/mysql-files/us_cities.txt', 'US_Cities'); +--------------------------------------------------------------------------------+ | gen_dictionary_load('/usr/local/mysql/mysql-files/us_cities.txt', 'US_Cities') | +--------------------------------------------------------------------------------+ | Dictionary load success | +--------------------------------------------------------------------------------+

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

Press CTRL+C to copy
mysql> SELECT gen_dictionary('DE_Cities'); +-----------------------------+ | gen_dictionary('DE_Cities') | +-----------------------------+ | Berlin | +-----------------------------+ mysql> SELECT gen_dictionary('US_Cities'); +-----------------------------+ | gen_dictionary('US_Cities') | +-----------------------------+ | Phoenix | +-----------------------------+

从多个词典中选择随机项,可以首先随机选择一个词典,然后从其中选择项:

Press CTRL+C to copy
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() 函数使得一个词语从一个词典中被替换为另一个词典中的词语,这样可以实现通过替换来进行masking。它的参数是要替换的词语、词语所在的词典和选择替换词语的词典,例如,可以将美国城市替换为德国城市,或者反之,使用gen_blocklist()如下方式:

Press CTRL+C to copy
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() 将其保持不变:

Press CTRL+C to copy
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: 客户社会安全号码。

例如,这个表可能被定义如下:

Press CTRL+C to copy
CREATE TABLE customer ( id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, first_name VARCHAR(40), last_name VARCHAR(40), ssn VARCHAR(11) );

客户服务代表应用程序用来检查客户 SSN 的查询语句可能是这样:

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

然而,这样就暴露了SSN给客户服务代表,代表无需看到除了最后四位数字以外的任何内容。相反,应用程序可以使用这个查询来显示只masked SSN:

Press CTRL+C to copy
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 | XXX-XX-0007 | +-----+-------------+

现在代表只看到必要的信息,客户隐私得以保留。

为什么使用CONVERT()函数作为mask_ssn()的参数?因为mask_ssn()需要11个字符的参数。因此,即使ssn定义为VARCHAR(11),如果ssn列具有多字节字符集,它可能在传递给可加载函数时看起来超过11个字节,从而出现错误。将值转换为二进制字符串确保函数看到11个字符。

类似技术也可能用于其他数据masking函数,字符串参数不具有单字节字符集的情况。

如果masked数据来自表,用于多个查询可能很方便定义一个视图来生产masked数据。这样应用程序可以从视图中选择,而不需要在单个查询中执行masking。

例如,之前节中的customer表的masking视图可以定义如下:

Press CTRL+C to copy
CREATE VIEW masked_customer AS SELECT id, first_name, last_name, mask_ssn(CONVERT(ssn USING binary)) AS masked_ssn FROM customer;

然后查找客户的查询变得简单,但是仍然返回masked数据:

Press CTRL+C to copy
mysql> SELECT id, masked_ssn mysql> FROM masked_customer mysql> WHERE first_name = 'Joanna' AND last_name = 'Bond'; +-----+-------------+ | id | masked_ssn | +-----+-------------+ | 786 | XXX-XX-0007 | +-----+-------------+