Cassandra 文件

版本

您正在檢視預發行版本的說明文件。

動態資料遮罩 (DDM)

動態資料遮罩 (DDM) 會隱藏敏感資訊,同時仍允許存取已遮罩的欄位。DDM 不會變更儲存的資料。相反地,它只會在 SELECT 查詢期間以其模糊的形式呈現資料。這旨在提供一定程度的保護,以防止意外資料外洩。但是,任何有權直接存取 SSTable 檔案的人員都將能夠讀取清除的資料。

遮罩函數

DDM 基於一組 CQL 原生函數,這些函數會隱藏敏感資訊。可用的函數為

函數 說明

mask_null(value)

將第一個參數替換為 null 欄位。傳回值永遠是非存在欄位,而不是表示 null 值的非 null 欄位。

範例

mask_null('Alice')null

mask_null(123)null

mask_default(value)

用相同類型的任意固定預設值替換其參數。對於文字值,這將是 ****,對於數字值,這將是零,對於布林值,這將是 false,依此類推。

可變長度多值類型(例如清單、集合和映射)會被遮罩為空集合。

固定長度多值類型(例如元組、使用者定義類型 (UDT) 和向量)會被遮罩,方法是將其每個值替換為該值類型的預設遮罩值。

範例

mask_default('Alice')'****'

mask_default(123)0

mask_default((list<int>) [1, 2, 3])[]

mask_default((vector<int, 3>) [1, 2, 3])[0, 0, 0]

mask_replace(value, replacement])

取代第二個引數中的第一個引數為替換值。替換值需要與被取代的值為相同類型。

範例

mask_replace('Alice', 'REDACTED')'REDACTED'

mask_replace(123, -1)-1

mask_inner(value, begin, end, [padding])

傳回第一個textvarcharascii引數的副本,將除了第一個和最後一個以外的每個字元替換為填充字元。第二個和第三個引數是公開的前綴和後綴大小。選擇性的第四個引數是填充字元,預設為\*

範例

mask_inner('Alice', 1, 2)'Ace'

mask_inner('Alice', 1, null)'A'

mask_inner('Alice', null, 2)'*ce'

mask_inner('Alice', 2, 1, '#')'Al##e'

mask_outer(value, begin, end, [padding])

傳回第一個textvarcharascii引數的副本,將第一個和最後一個字元替換為填充字元。第二個和第三個引數是公開的前綴和後綴大小。選擇性的第四個引數是填充字元,預設為\*

範例

mask_outer('Alice', 1, 2)'*li'

mask_outer('Alice', 1, null)'*lice'

mask_outer('Alice', null, 2)'Ali'

mask_outer('Alice', 2, 1, '#')'##ic#'

mask_hash(value, [algorithm])

傳回包含第一個引數雜湊的blob。選擇性的第二個引數是根據可用的 Java 安全提供者要使用的雜湊演算法。預設雜湊演算法為SHA-256

範例

mask_hash('Alice')

mask_hash('Alice', 'SHA-512')

這些函數可以用於SELECT查詢,以取得資料的模糊檢視。例如

CREATE TABLE patients (
   id timeuuid PRIMARY KEY,
   name text,
   birth date
);

INSERT INTO patients(id, name, birth) VALUES (now(), 'alice', '1982-01-02');
INSERT INTO patients(id, name, birth) VALUES (now(), 'bob', '1982-01-02');

SELECT mask_inner(name, 1, null), mask_default(birth) FROM patients;

//   system.mask_inner(name, 1, NULL) | system.mask_default(birth)
// -----------------------------------+----------------------------
//                                b** |                 1970-01-01
//                              a**** |                 1970-01-01

將遮罩函數附加到表格欄位

遮罩函數可以永久附加到表格的任何欄位。如果定義了遮罩欄位,SELECT查詢將永遠以遮罩形式傳回欄位值。遮罩對執行SELECT查詢的使用者來說是透明的。知道欄位已被遮罩的唯一方法是參閱表格定義。

這是一個預設停用的選擇性功能。若要使用此功能,請在cassandra.yaml中啟用dynamic_data_masking_enabled屬性。

表格欄位的遮罩可以在CREATE TABLE中定義,以建立表格架構。這個範例使用具有兩個引數的mask_inner函數

CREATE TABLE patients (
    id timeuuid PRIMARY KEY,
    name text MASKED WITH mask_inner(1, null),
    birth date MASKED WITH mask_default()
 );

在這個資料上使用 SELECT 查詢時,mask_inner 函數需要三個參數,但當將函數附加到表格架構時,第一個參數總是會被省略。第一個參數的值總是會被解釋為遮罩欄位的數值,在本例中為 text 欄位。

基於相同原因,在建立表格架構時,使用遮罩函數 mask_default 沒有任何參數,但在 SELECT 查詢中使用時需要一個參數。

資料可以正常插入遮罩表格中,而不會被變更。例如

INSERT INTO patients(id, name, birth) VALUES (now(), 'alice', '1984-01-02');
INSERT INTO patients(id, name, birth) VALUES (now(), 'bob', '1982-02-03');

SELECT 查詢將會傳回遮罩資料。遮罩函數將會自動套用至欄位值。

SELECT name, birth FROM patients;

//  name  | birth
// -------+------------
//  a**** | 1970-01-01
//    b** | 1970-01-01

ALTER TABLE 查詢可用於變更表格欄位上的遮罩函數。

ALTER TABLE patients ALTER name
  MASKED WITH mask_default();

類似地,遮罩函數可以使用 ALTER TABLE 查詢從欄位中分離。

ALTER TABLE patients ALTER name
  DROP MASKED;

權限

一般使用者在建立時沒有 UNMASK 權限,並且會看到遮罩值。授予使用者 UNMASK 權限,讓他們可以擷取遮罩欄位的未遮罩值。超級使用者會在建立時自動取得 UNMASK 權限,並且會在 SELECT 查詢結果中看到未遮罩值。

例如,假設我們有一個包含遮罩欄位的表格

CREATE TABLE patients (
    id timeuuid PRIMARY KEY,
    name text MASKED WITH mask_inner(1, null),
    birth date MASKED WITH mask_default()
 );

然後我們在表格中插入一些資料

INSERT INTO patients(id, name, birth) VALUES (now(), 'alice', '1984-01-02');
INSERT INTO patients(id, name, birth) VALUES (now(), 'bob', '1982-02-03');
LOGIN unprivileged
SELECT name, birth FROM patients;

//  name  | birth
// -------+------------
//  a**** | 1970-01-01
//    b** | 1970-01-01

接著我們為表格建立兩個具有 SELECT 權限的使用者,但我們只授予其中一個使用者 UNMASK 權限

CREATE USER privileged WITH PASSWORD 'xyz';
GRANT SELECT ON TABLE patients TO privileged;
GRANT UNMASK ON TABLE patients TO privileged;

CREATE USER unprivileged WITH PASSWORD 'xyz';
GRANT SELECT ON TABLE patients TO unprivileged;

具有 UNMASK 權限的使用者可以看到明確的未遮罩資料

LOGIN privileged
SELECT name, birth FROM patients;

//  name  | birth
// -------+------------
//  alice | 1984-01-02
//    bob | 1982-02-03

沒有 UNMASK 權限的使用者只能看到遮罩資料

LOGIN unprivileged
SELECT name, birth FROM patients;

//  name  | birth
// -------+------------
//  a**** | 1970-01-01
//    b** | 1970-01-01

UNMASK 權限就像任何其他權限一樣,可以隨時撤銷

REVOKE UNMASK ON TABLE patients
  FROM privileged;

請注意,當驗證已停用時,匿名預設使用者具有所有權限,包括 UNMASK 權限,並且可以看到未遮罩資料。換句話說,只有在啟用驗證時,將資料遮罩函數附加到欄位才有意義。

只有具有 UNMASK 權限的使用者才能在 SELECT 查詢的 WHERE 子句中使用遮罩欄位。沒有 UNMASK 權限的使用者無法使用此功能。此功能可防止惡意使用者透過執行窮舉式暴力破解查詢來查看明確資料。沒有 UNMASK 權限的使用者將會看到以下內容

CREATE USER untrusted_user WITH PASSWORD 'xyz';
GRANT SELECT ON TABLE patients TO untrusted_user;
LOGIN untrusted_user
SELECT name, birth FROM patients WHERE name = 'Alice' ALLOW FILTERING;

// Unauthorized: Error from server: code=2100 [Unauthorized] message="User untrusted_user has no UNMASK nor SELECT_UNMASK permission on table k.patients"

在某些使用案例中,受信任的資料庫使用者需要產生未受信任的外部使用者將會查詢的遮罩資料。例如,受信任的應用程式可以連線到資料庫,並透過查詢擷取將顯示給其最終使用者的遮罩資料。在這種情況下,可以授予受信任的使用者 (應用程式) SELECT_MASKED 權限。此權限讓使用者可以在 SELECT 查詢的 WHERE 子句中查詢遮罩欄位,同時仍然只在查詢結果中看到遮罩資料

CREATE USER trusted_user WITH PASSWORD 'xyz';
GRANT SELECT, SELECT_MASKED ON TABLE patients TO trusted_user;
LOGIN trusted_user
SELECT name, birth FROM patients WHERE name = 'Alice' ALLOW FILTERING;

//  name  | birth
// -------+------------
//  a**** | 1970-01-01

自訂函式

使用者定義函式 (UDF) 可以附加到資料表欄位。用於遮罩的 UDF 應屬於與遮罩資料表相同的鍵空間。要遮罩的欄位值將傳遞為附加 UDF 的第一個引數。因此,附加到欄位的 UDF 應至少有一個引數,而且該引數應與遮罩欄位具有相同的類型。此外,附加的 UDF 應傳回與遮罩欄位相同的類型值

CREATE FUNCTION redact(input text)
   CALLED ON NULL INPUT
   RETURNS text
   LANGUAGE java
   AS 'return "redacted";';

CREATE TABLE patients (
   id timeuuid PRIMARY KEY,
   name text MASKED WITH redact(),
   birth date
);

這會在資料表架構和函式之間建立相依性。在這個相依性存在時,任何嘗試刪除函式的動作都將遭到拒絕。因此,您必須先刪除資料表中的遮罩欄位,才能刪除函式

ALTER TABLE patients ALTER name
  DROP MASKED;

刪除欄位、包含欄位的資料表或包含資料表的鍵空間也會移除相依性。

聚合函式 無法用作遮罩函式。