文件首頁
MySQL 8.4 參考手冊
相關文件 下載本手冊
PDF (US Ltr) - 39.9Mb
PDF (A4) - 40.0Mb
Man Pages (TGZ) - 258.5Kb
Man Pages (Zip) - 365.5Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 8.4 參考手冊  /  ...  /  使用 MySQL Enterprise 資料遮罩和去識別化元件

8.5.2.2 使用 MySQL Enterprise 資料遮罩和去識別化元件

在使用 MySQL Enterprise 資料遮罩和去識別化之前,請依照第 8.5.2.1 節「MySQL Enterprise 資料遮罩和去識別化元件安裝」中提供的指示進行安裝。

若要在應用程式中使用 MySQL Enterprise 資料遮罩和去識別化,請叫用適合您要執行之作業的函式。如需詳細的函式描述,請參閱第 8.5.2.4 節「MySQL Enterprise 資料遮罩和去識別化元件函式描述」。本節將示範如何使用函式來執行一些代表性的工作。它首先概述可用的函式,然後提供一些關於如何在真實環境中使用這些函式的範例。

遮罩資料以移除識別特徵

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') |
+------------------------------+
| ayxnqu.xmkpvvyr@mynet.com    |
+------------------------------+

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 Enterprise Data Masking and De-Identification 允許使用字典作為隨機值來源,稱為詞彙。要使用字典,必須先將其新增至 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 |
+-----+-------------+

現在,代表只看到必要的資訊,並且保留了客戶隱私。

為什麼對 mask_ssn() 的引數使用了 CONVERT() 函式?因為 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 |
+-----+-------------+