第23回:Oracle Data Redactionについて

技術者向け・データベースの技術情報発信

皆様こんにちは。
今回はOracle Databaseにて使用できるセキュリティ機能である、Oracle Data Redactionについてご紹介します。

1. Oracle Data Redactionとは

Oracle Data Redactionは、権限を持たないユーザやアプリケーションによるデータの問い合わせに対し、データをマスキングして表示させる機能で、Oracle Databaseで使用することができます。
この機能には以下の特徴があります。

  • データのマスキングによって不正アクセスから情報を保護することができる
  • マスキングは情報を表示する際に行われ、実データは変更されない
  • 情報の保護を既存のアプリケーションプログラムの変更なしで行うことができる
  • クレジットカード業界のセキュリティ基準(PCI DSS)やマイナンバー制度に対応するため、主に金融機関や公的機関のお客様に使用されている

なお、Oracle Data RedactionはOracle Database Enterprise Editionで利用できるオプション「Oracle Advanced Security」の機能の一つです。

2. リダクションの種類

Oracle Data Redactionを使用した列(カラム)のマスキングを「リダクション」と呼びます。
リダクションには以下4つの種類があり、それぞれ特徴が異なります。

  • 完全リダクション:表またはビューの指定した列の内容全体をリダクションする
  • 部分リダクション:表示される出力の一部をリダクションする
  • ランダムリダクション:値全体をランダムな値に置換してリダクションする
  • 正規表現によるリダクション:正規表現を使用して、パターン検索に基づいて列データ内にある特定のデータをリダクションする

上記それぞれのリダクションを使用した場合に、リダクション対象としたテーブルの列がどのようにリダクションされるかは「表1. リダクションの種類ごとのリダクション結果」の通りとなります。

表1. リダクションの種類ごとのリダクション結果
項番 リダクションの種類 リダクション対象列のデータ型
文字型 数値型 日時型
1 完全リダクション 空白 0(ゼロ) 01-JAN-01
2 部分リダクション 任意の文字 任意の数値 任意の日時
3 ランダムリダクション ランダムな文字 ランダムな数値 ランダムな日時
4 正規表現によるリダクション 任意の文字 リダクション不可 リダクション不可

では、実際にリダクションを使用した例をご覧ください。

3.リダクションの使用例

リダクションの設定は「DBMS_REDACT」パッケージを使用して行います。
リダクション定義の追加は「DBMS_REDACT.ADD_POLICY」プロシージャを使用します。

今回リダクションを実施した環境はこちらになります。
OS:Red Hat Enterprise Linux 7.6
DB:Oracle Database 12c Release 2

また、リダクションに使用したテーブルの定義及び内容は以下の通りとなります。
SQL> create table card_info
  2  (
  3  id NUMBER(10),
  4  card_num VARCHAR2(20),
  5  PRIMARY KEY(id)
  6  );

データ挿入後のcard_info表のselect結果は以下の通りです。

SQL> select * from card_info order by id;

	ID CARD_NUM
---------- --------------------
	 1 5156-3509-2372-7681
	 2 3002-4312-5548-6839
	 3 1495-8082-2571-4064
	 4 0865-4523-3618-5241

完全リダクション(FULL)

card_info表のcard_num列に完全リダクションのポリシーを作成します。
card_num列のデータ型は文字型であるため、完全リダクションを設定すると問い合わせ結果は空白で表示されます。
SQL> BEGIN
  2   DBMS_REDACT.ADD_POLICY(
  3     object_schema		=> 'oracle', 
  4     object_name		=> 'card_info', 
  5     column_name		=> 'card_num',
  6     policy_name		=> 'redact_full_card', 
  7     function_type		=> DBMS_REDACT.FULL,
  8     expression			=> '1=1');
  9  END;
 10  /
 PL/SQLプロシージャが正常に完了しました。

リダクションを設定した結果、どのように表示されるか確認してみましょう。

SQL> select * from card_info order by id;

    ID CARD_NUM
  --------- ----------------
	 1	
	 2	
	 3	
	 4		

card_num列のデータ型が空白でリダクションされたことが確認できました。

部分リダクション(PARTIAL)

card_info表のcard_num列に部分リダクションを作成します。
今回の例では、「DBMS_REDACT.REDACT_CCN16_F12」というリダクション形式を使用しています。
これは、最後の4桁は表示したまま、16桁の番号をリダクションする、という形式です。
SQL> BEGIN
  2   DBMS_REDACT.ADD_POLICY(
  3     object_schema		=> 'oracle', 
  4     object_name		=> 'card_info', 
  5     column_name		=> 'card_num',
  6     policy_name		=> 'redact_partial_card', 
  7     function_type		=> DBMS_REDACT.PARTIAL,
  8     function_parameters	=> DBMS_REDACT.REDACT_CCN16_F12,
  9     expression			=> '1=1');
 10  END;
 11  /

PL/SQLプロシージャが正常に完了しました。

リダクションを設定した結果、どのように表示されるか確認してみましょう。

SQL> select * from card_info order by id;

	ID CARD_NUM
---------- --------------------
	 1 ****-****-****-7681
	 2 ****-****-****-6839
	 3 ****-****-****-4064
	 4 ****-****-****-5241

最後の4行を表示したまま16桁の番号をリダクションされていることが確認できました。

ランダムリダクション(RANDOM)

card_info表のcard_num列にランダムリダクションを作成します。
Card_num列は文字型であるため、ランダムリダクションを設定すると、問い合わせ結果はランダムな文字列が表示されます。

SQL> BEGIN
  2   DBMS_REDACT.ADD_POLICY(
  3     object_schema		=> 'oracle', 
  4     object_name		=> 'card_info', 
  5     column_name		=> 'card_num',
  6     policy_name		=> 'redact_random_card', 
  7     function_type		=> DBMS_REDACT.RANDOM,
  8     expression			=> '1=1');
  9  END;
 10  /

PL/SQLプロシージャが正常に完了しました。

リダクションを設定した結果、どのように表示されるか確認してみましょう。

SQL> select * from card_info order by id;

  ID CARD_NUM
  ---------- --------------------
  1 2D@E&d¥]:LHM.ldeBTP
  2 t;@=v<,<|CHE~D4D%KP
  3 N0dDu4(BV8lL}<0j^@t
  4 IS?F?Id}Q[GNGQl&YcO

card_num列がランダムな文字列でリダクションされていることが確認できました。

正規表現によるリダクション(REGEX)

card_info表のcard_num列に正規表現のリダクションポリシーを作成します。
今回の例ではcard_num列の先頭4桁を「####」でリダクションする設定を行います。

SQL> BEGIN
  2		DBMS_REDACT.ADD_POLICY(
  3		object_schema			=> 'oracle',
  4		object_name			=> 'card_info',
  5		column_name			=> 'card_num',
  6		policy_name			=> 'redaction_regexp_card',
  7		function_type			=> DBMS_REDACT.REGEXP,
  8		expression				=> '1=1',
  9		regexp_pattern			=> '^d{4}',		※注1 リダクション対象を正規表現で指定
 10		regexp_replace_string	=> '####',		※注2 リダクションに使用する文字列
 11		regexp_position			=> 1,
 12		regexp_occurrence		=> DBMS_REDACT.RE_ALL); 
 13	END;
 14	/

PL/SQLプロシージャが正常に完了しました。

リダクションを設定した結果、どのように表示されるか確認してみましょう。

SQL> select * from card_info order by id;

	ID CARD_NUM
---------- ---------------------------------------------------------------------
	 1 ####-3509-2372-7681
	 2 ####-4312-5548-6839
	 3 ####-8082-2571-4064
	 4 ####-4523-3618-5241

先頭4文字が「####」でリダクションされていることが確認できました。

4. まとめ

リダクションポリシーを作成する場合は、表に格納されているデータ型によってリダクション結果が変化しますので、設計を行う際には注意する必要があります。
このブログがOracle Data Redactionを導入する際の一助になれば幸いです。