Oracle TDE 表領域暗号化④|SYSTEM・SYSAUX・UNDO・TEMPを暗号化:統計・AWR経由の平文漏洩を実機で塞ぐ

【連載】Oracle TDE 表領域暗号化を実機で検証する
  1. 設計と基本構築
  2. 守れる範囲・守れない範囲
  3. 鍵の管理:失えばデータは二度と戻らない
  4. SYSTEM・SYSAUX・UNDO・TEMPを暗号化:統計・AWR経由の平文漏洩を塞ぐ(この記事)

この記事について

本記事は、Oracle Database 19c の TDE 表領域暗号化を実機で検証する連載の第4回(続編)です。

連載の第2回で、ユーザー表領域を暗号化しても、統計(SYSTEM表領域)にはヒストグラムの実値が、SYSAUX表領域にはAWRに記録されたリテラル入りSQLの全文が、平文でコピーされることを実機で確認しました。 本記事では、この漏洩を防ぐため、残っていた SYSTEM・SYSAUX・UNDO・TEMP をすべて暗号化します

連載の全体マップ:

記事タイトル内容
第1回設計と基本構築——盗まれたデータファイルを読ませない脅威モデル・方式設計・盗難実証(before)・ウォレット/鍵構築・守られる実証(after)
第2回守れる範囲・守れない範囲——ユーザー表領域が暗号化済みなのに平文が残る場所はどこかUNDO/TEMP・統計(SYSTEM)・AWR(SYSAUX)への平文コピーの検証
第3回鍵の管理——失えばデータは二度と戻らない既存表領域のオンライン暗号化移行・ウォレットファイルはいつ必要か・鍵バックアップとDR
第4回(本記事)SYSTEM・SYSAUX・UNDO・TEMPを暗号化——統計・AWR経由の平文漏洩を実機で塞ぐ統計・AWRの平文漏洩を防ぐbefore/after・UNDO/TEMPの暗号化・REDOに平文が残る検証

想定読者:

  • 第2回を読んで「統計やAWRに残る平文はどう対処するのか」が気になっていた方
  • SYSTEM・SYSAUX・UNDO・TEMPの暗号化を、稼働中に実行できるのか・副作用はないのかまで実測で確かめたい方
  • TDE導入済みDBの暗号化範囲をどこまで広げるかを設計している方

前提知識:

  • 第2回の内容(統計・AWRから平文が漏れる仕組み・strings | grep での覗き方)
  • SQL*Plus・Linux の基本操作

第2回がまだの方は、先に「守れる範囲・守れない範囲」を読むと、本記事で扱う問題点が具体的にわかります。

検証環境

項目
VMdb-node(Oracle Linux 8.9)
DBバージョンOracle Database 19c Enterprise Edition 19.28.0.0.0
構成非CDB(non-multitenant)
ORACLE_SIDorcl19u
TDE設定WALLET_ROOT 方式・自動ログインウォレット(LOCAL_AUTOLOGIN)・ENCRYPT_NEW_TABLESPACES=ALWAYS
対象表領域SYSTEM・SYSAUX・UNDO・TEMP

連載①〜③で構築した環境をベースに使います。機密データ用のユーザー表領域は暗号化済みで、第2回の検証で統計・AWRにコピーされた平文が残った状態からスタートします。

ライセンス前提: TDE(表領域暗号化)は Oracle Enterprise Edition + Advanced Security オプションの機能です。Standard Edition (SE2) では利用できません。本連載はこの前提で構築しています。


1. 第2回で漏れた平文は、まだディスクに残っているか — before

第2回の検証では、暗号化表の機密値が SYSTEM に5件(統計のヒストグラム実値 STATLEAK-… とカード番号)、SYSAUX に1件(AWRのSQLに埋め込まれたカード番号)、平文で見えていました。

まず、その平文が今もディスクに残っているかを、第2回と同じ strings | grep で確認します。

SQL> !strings /u01/app/oracle/oradata/ORCL19U/system01.dbf | grep -cE 'STATLEAK|4811-1111-1111-1111'
4

SQL> !strings /u01/app/oracle/oradata/ORCL19U/sysaux01.dbf | grep -cE 'STATLEAK|4811-1111-1111-1111'
2

SYSTEM に4件・SYSAUX に2件、今も平文のまま残っています(第2回とは grep のパターンを変えているため件数は一致しませんが、パターンが機密値そのものなので、ヒット=実値が読める状態です)。

注目すべきは SYSAUX 側です。 第2回では、カード番号をリテラルに含むSQLに /* leaktest9 */ という目印のコメントを付けてAWRに記録させました(/*+ ... */ のヒントとは違い、ただのコメントです。SQL文はコメント込みで DBA_HIST_SQLTEXT に保存されるため、後から自分の検証SQLだけを拾えます)。 この目印でAWRのビューを確認すると——

SQL> SELECT sql_text FROM dba_hist_sqltext WHERE sql_text LIKE '%leaktest9%';

レコードが選択されませんでした。

第2回でAWRに記録させたリテラルSQLは、AWRの保持期間を過ぎてビューからは既に見えなくなっています。 それでも、冒頭の strings で見たとおり、ディスク上には平文が残っています。 ビューから消えることと、ディスクから消えることは別です。第3回で触れた「退役したHDD/SSDには、OSが上書きするまで古い平文ブロックが残る」のと同じ構図が、DBの中でも起きているわけです。

この「ビューでは追えないがディスクには残る」状態こそ、ディスク窃取・退役HDDの脅威(連載①の脅威モデルA)に対して、暗号化で対処すべき対象です。

では、どう暗号化するか。対象の SYSTEM・SYSAUX・UNDO・TEMP は表領域の種類ごとに使える暗号化の方法が違うため、先に設計を整理してから手を動かします。


2. 設計の要点

項目決定理由
対象SYSTEM・SYSAUX・UNDO・TEMP第2回で実証した漏洩経路の格納先(統計・AWR=SYSTEM・SYSAUX)と平文の通り道(UNDO・TEMP)
方式表領域ごとに使える方法が違う(下表)稼働させたまま実施する。アルゴリズムは連載の標準 AES256 を明示
事前確認ウォレットOPEN鍵が使えない状態では暗号化そのものが実行できない

既存の表領域を暗号化する方法は3つあり、表領域の種類によって使えるものが違います。○×で整理すると、こうなります。ここが設計の分かれ目です。

表領域① オンライン暗号化
(無停止)
② オフライン変換
(DB停止あり)
③ 作り直して切替
(無停止)
本記事で採った方法
SYSTEM×① オンライン暗号化
SYSAUX×① オンライン暗号化
UNDO① オンライン暗号化
TEMP××③ 作り直して切替(唯一の方法)
  • ① オンライン暗号化ALTER TABLESPACE ... ENCRYPTION ONLINE ENCRYPT): DBをOPENしたまま=業務接続もインスタンスも止めずに実行できる。複数の表領域を別セッションで並列に暗号化することもできるが、SYSTEM・UNDOは他の表領域と同時に暗号化しないよう公式ドキュメントに注意がある(本記事は1つずつ順に実行する)
  • ② オフライン変換: SYSTEM・SYSAUX・UNDOは表領域単体をオフラインにできないため、DB全体を SHUTDOWNSTARTUP MOUNT(インスタンスは起動するがDBは開かない=サービス停止)にして変換する手順になる
  • ③ 作り直して切替: 暗号化版を新規作成して切り替え、旧を削除する。役割を差し替えられるUNDO・TEMPだけの方法(新しいSYSTEMを作って切替、はできない)。既存TEMPは①②とも不可のため、これが唯一の方法

実務では、暗号化のためだけにDBの停止時間を確保するのは簡単ではありません。稼働中のまま実施できることが採用の条件になる場面は多く、その場合は無停止でやれる①+③の組み合わせが事実上唯一の選択肢です。本記事も同じ前提に立ち、SYSTEM・SYSAUX・UNDO は①を、TEMPは③を採ります。 UNDOについては「現用(アクティブ)のUNDOのままで本当に通るのか」を「UNDO・TEMPも暗号化する」の節で実測します。 可否の出典は『Oracle Database Advanced Securityガイド』(19c)の「表領域およびデータベースの暗号化変換」です。


3. SYSTEM・SYSAUX を暗号化する

まず SYSTEM から、稼働中のまま暗号化していきます。

SQL> ALTER TABLESPACE SYSTEM ENCRYPTION ONLINE USING 'AES256' ENCRYPT;

表領域が変更されました。

この時点で、SYSTEM 側の平文がどうなったかを見ます。

SQL> !strings /u01/app/oracle/oradata/ORCL19U/system01.dbf | grep -cE 'STATLEAK|4811-1111-1111-1111'
0

SQL> !strings /u01/app/oracle/oradata/ORCL19U/sysaux01.dbf | grep -cE 'STATLEAK|4811-1111-1111-1111'
2

SYSTEM は0件になり、まだ暗号化していない SYSAUX には2件残ったまま——暗号化の効果が表領域単位で出ていることが、この途中経過からも分かります。

続いて SYSAUX を暗号化します。

SQL> ALTER TABLESPACE SYSAUX ENCRYPTION ONLINE USING 'AES256' ENCRYPT;

表領域が変更されました。

SQL> ALTER SYSTEM CHECKPOINT;

システムが変更されました。

SQL> SELECT tablespace_name, encrypted FROM dba_tablespaces WHERE tablespace_name IN ('SYSTEM','SYSAUX');

TABLESPACE_NAME                ENC
------------------------------ ---
SYSAUX                         YES
SYSTEM                         YES

after を同じ grep で確認します。

SQL> !strings /u01/app/oracle/oradata/ORCL19U/system01.dbf | grep -cE 'STATLEAK|4811-1111-1111-1111'
0

SQL> !strings /u01/app/oracle/oradata/ORCL19U/sysaux01.dbf | grep -cE 'STATLEAK|4811-1111-1111-1111'
0

beforeで SYSTEM に4件・SYSAUX に2件あった平文が、どちらも0件になりました。 第2回で「守らない」と特定した統計・AWR経由の平文が、ディスク上から読めなくなりました。

v$encrypted_tablespaces でも確認します。dba_tablespaces のYES/NOと違い、どのアルゴリズムで暗号化されたかまで見えるビューです(ts#だけだとどの表領域かわからないので、v$tablespace と結合して表領域名で表示します)。

SQL> SELECT t.name AS tablespace_name, e.encryptionalg, e.encryptedts FROM v$encrypted_tablespaces e JOIN v$tablespace t ON e.ts# = t.ts# WHERE t.name IN ('SYSAUX','SYSTEM') ORDER BY t.name;

TABLESPACE_NAME                ENCRYPT ENC
------------------------------ ------- ---
SYSAUX                         AES256  YES
SYSTEM                         AES256  YES

指定どおり、どちらも AES256 で暗号化されています。


4. 暗号化しても「見える」もの — TDEの守備範囲は変わらない

ここで確認しておきたいのが、暗号化しても変わらないものです。 統計のヒストグラムをビュー経由で見ます。第2回では表の所有ユーザーで user_tab_histograms を参照しましたが、今回はSYSで作業しているため、同じ内容を全スキーマ横断で見られる dba_tab_histograms を使います。

SQL> SELECT column_name, endpoint_actual_value FROM dba_tab_histograms
     WHERE table_name='HR_SECRET_ENC' AND column_name='NAME' AND endpoint_actual_value LIKE 'STATLEAK%';

COLUMN_NAME   ENDPOINT_ACTUAL_VALUE
------------- ----------------------
NAME          STATLEAK-SATO
NAME          STATLEAK-SUZUKI
NAME          STATLEAK-TANAKA

実値が今も表示されます。 TDEはディスク上のデータを暗号化するだけで、認可されたDB経由のアクセスには透過だからです(連載①の脅威モデルで「守らない」と整理した領域です)。

つまり、SYSTEM・SYSAUXの暗号化で防げるのはディスク窃取・退役HDD経由の漏洩であって、DBにログインできる相手には効きません。 ログインできる相手に対処するには、表示段階で実値を隠す Data Redaction やデータマスキング、アクセス制御と最小権限の徹底、管理者権限そのものを統制する Database Vault といった、TDEとは別の層が必要です。これらは本連載のスコープ外のため、別記事で取り上げます。

第2回で挙げた運用側の対策——機密値はバインド変数・機密列にヒストグラムを作らない——は、暗号化後も引き続き有効な対策です。

  • 暗号化=「ディスクを盗まれても読めない」を統計・AWRにも広げる
  • バインド変数など=「そもそも実値のコピーを作らない」

役割が違うので、両方やるのが多層防御です。


5. UNDO・TEMP も暗号化する — 「漏れない」のに、なぜ

第2回で実証したとおり、UNDO・TEMPに書かれた内容が暗号化されるかどうかは、書き先ではなく元データ(更新やソートの対象になった表)が置かれている表領域の暗号化に従います。 暗号化表領域の表なら、そのUNDO・TEMPも自動で暗号化されます。一方、非暗号化表領域の表のデータは平文のまま残ります(第2回の実測:非暗号化の表のDELETE 2000行 → UNDOに2000件の平文)。 本環境にも暗号化していない表領域(USERS など)は残るため、書き先(UNDO・TEMP)側を暗号化して、ソースを問わず守られる状態にします。 平文が残るのは「ソースと書き先の両方が非暗号化のとき」だけ——この完全条件を、書き先側から閉じるのが多層防御としてのUNDO・TEMP暗号化です。

5-1. UNDO — 現用のまま、オンライン暗号化できるか

「設計の要点」の表のとおり、UNDOはSYSTEM・SYSAUXと同じオンライン暗号化が使えます。 ただしUNDOは、インスタンスが今まさに使っている現用の表領域です。稼働中のまま本当に通るのか——ここを実測します。

まずbefore。現用のUNDO(UNDOTBS1)が暗号化されていない状態で、非暗号化表領域(USERS)の表にマーカー2,000行を入れて削除し(DELETEは行まるごとの変更前イメージがUNDO行き=いちばん強い漏洩テスト)、UNDOのデータファイルを覗きます。

SQL> CREATE TABLE undo_onl_plain (id NUMBER, name VARCHAR2(30), card VARCHAR2(20)) TABLESPACE users;

表が作成されました。

SQL> INSERT INTO undo_onl_plain SELECT LEVEL, 'UNDO-ONL-BEFORE-0721', '4123-0000-0000-0000' FROM dual CONNECT BY LEVEL <= 2000;

2000行が作成されました。

SQL> COMMIT;

コミットが完了しました。

SQL> DELETE FROM undo_onl_plain;

2000行が削除されました。

SQL> COMMIT;

コミットが完了しました。

SQL> ALTER SYSTEM FLUSH BUFFER_CACHE;

システムが変更されました。

SQL> ALTER SYSTEM CHECKPOINT;

システムが変更されました。

SQL> !strings /u01/app/oracle/oradata/ORCL19U/undotbs01.dbf | grep -c -E 'UNDO-ONL-BEFORE-0721|4123-0000'
4000

4,000件ヒット(2,000行×氏名・カード番号の2値)。第2回の実測どおり、暗号化していないUNDOには非暗号化ソースの平文がそのまま残ります。

この状態のまま、現用UNDOをオンライン暗号化します。

SQL> ALTER TABLESPACE undotbs1 ENCRYPTION ONLINE USING 'AES256' ENCRYPT;

表領域が変更されました。

SQL> SELECT tablespace_name, encrypted FROM dba_tablespaces WHERE tablespace_name='UNDOTBS1';

TABLESPACE_NAME                ENC
------------------------------ ---
UNDOTBS1                       YES

現用のUNDOのまま、エラーなく通りました。 では、さっきの4,000件はどうなったか。

SQL> !strings /u01/app/oracle/oradata/ORCL19U/undotbs01.dbf | grep -c -E 'UNDO-ONL-BEFORE-0721|4123-0000'
0

0件。オンライン暗号化は「暗号化版のファイルを別に作り、完成後に差し替える」しくみなので(第3回で確認した機構)、変換前の平文ブロックは新しいファイルに持ち越されません。

afterも対称に取ります。同じ表・同じ操作で、マーカーだけ変えて——

SQL> INSERT INTO undo_onl_plain SELECT LEVEL, 'UNDO-ONL-AFTER-0721', '4124-0000-0000-0000' FROM dual CONNECT BY LEVEL <= 2000;

2000行が作成されました。

(以降、DELETE 2000行 → COMMIT → FLUSH BUFFER_CACHE → CHECKPOINT:beforeと同一の操作)

SQL> !strings /u01/app/oracle/oradata/ORCL19U/undotbs01.dbf | grep -c -E 'UNDO-ONL-AFTER-0721|4124-0000'
0

同じ操作で 4,000件 → 0件。書き先(UNDO)が暗号化されていれば、非暗号化ソースのデータでも平文は残りません。

5-2. TEMP — 作り直して切り替える

TEMPだけは、既存の表領域をオンライン暗号化できません(「設計の要点」の表)。 公式ドキュメントの案内どおり、暗号化したTEMPを新規作成 → DB既定を切替 → 旧TEMPを削除の3手です。

SQL> CREATE TEMPORARY TABLESPACE temp_enc TEMPFILE '/u01/app/oracle/oradata/ORCL19U/temp_enc01.dbf' SIZE 200M ENCRYPTION USING 'AES256' ENCRYPT;

表領域が作成されました。

SQL> ALTER DATABASE DEFAULT TEMPORARY TABLESPACE temp_enc;

データベースが変更されました。

SQL> SELECT property_value FROM database_properties WHERE property_name='DEFAULT_TEMP_TABLESPACE';

PROPERTY_VALUE
--------------------------------------------------------------------------------
TEMP_ENC

SQL> DROP TABLESPACE temp INCLUDING CONTENTS AND DATAFILES;

表領域が削除されました。

書き先の暗号化が効いていることは、UNDOと同じ形で実測しています。 非暗号化ソースのマーカー2,000行をソート溢れさせ(ソート用メモリを64KBに絞って強制・sorts (disk) の増加で溢れの成立を確認)、新しいTEMPのファイルをgrep——

SQL> !strings /u01/app/oracle/oradata/ORCL19U/temp_enc01.dbf | grep -c -E 'TEMP-ONL-0723|4125-0000'
0

0件。 UNDO・TEMPの両面で、平文が残るのは「ソースと書き先の両方が非暗号化のとき」だけ——という完全条件が実測で閉じました。

5-3. 注意点 — どれも、やり残してもエラーは出ない

実は本環境では、この作業で2つの失敗をしています。いずれも後から気づいて直しましたが、共通するのは失敗した時点ではエラーが出ないことです。上のログの手順に対応する形で残します。

  1. TEMPの切替は「DB既定」まで——ALTER USER だけではDB既定は変わりません。放置すると、一般ユーザーのソート溢れは暗号化していないTEMPに平文で書かれ続け、暗号化TEMPを作った意味がなくなります(本環境はこれに気づかず放置していました)。切替と DATABASE_PROPERTIES の確認をセットにします
  2. 旧TEMPはDROPでファイルごと確定——暗号化前に書かれた平文が上書きで消えている保証はありません(beforeで見たとおり、SYSTEM・SYSAUXの平文は残り続けていました)。残っていれば、ディスク窃取・退役HDDの際にそのファイルだけ平文で読まれます。「消えているかもしれない」に頼らず消します

6. 管理系の表領域を暗号化しても、REDOログには平文が残る

ここまでの状態を、本記事に関係する表領域だけに絞って確認します。

SQL> SELECT tablespace_name, contents, encrypted FROM dba_tablespaces WHERE tablespace_name IN ('SYSTEM','SYSAUX','UNDOTBS1','TEMP_ENC','USERS') ORDER BY 1;

TABLESPACE_NAME                CONTENTS              ENC
------------------------------ --------------------- ---
SYSAUX                         PERMANENT             YES
SYSTEM                         PERMANENT             YES
TEMP_ENC                       TEMPORARY             YES
UNDOTBS1                       UNDO                  YES
USERS                          PERMANENT             NO

対象の SYSTEM・SYSAUX・UNDO・TEMP は、すべて暗号化されました。 一方 USERS は「機密データを置かない」前提で、暗号化せずに残しています。「すべて暗号化」が目的なのではなく、どこを守り・どこを守らないかを明示して選ぶ(連載①の脅威モデル)方針です。 では、これで平文の行き先はすべてなくなったのでしょうか。 最後にもう1つの通り道——REDOログ——を、この状態で実測します。

第2回と前節で見たとおり、UNDO・TEMPへの書き込みはソースの表領域に従いました。 REDOも同じ理屈なら、USERS への書き込みはREDOに平文で残るはずです。 目印1,000行を書き込み、REDOログファイルを直接覗きます。

SQL> CREATE TABLE redo_leak_plain (id NUMBER, name VARCHAR2(30), card VARCHAR2(20)) TABLESPACE users;

表が作成されました。

SQL> INSERT INTO redo_leak_plain SELECT LEVEL, 'REDOPLAIN-0720', '4111-9999-9999-9999'
  2    FROM dual CONNECT BY LEVEL <= 1000;

1000行が作成されました。

SQL> COMMIT;

コミットが完了しました。

SQL> !for f in /u01/app/oracle/oradata/ORCL19U/redo0*.log; do echo "== $f"; strings $f | grep -c -E 'REDOPLAIN-0720|4111-9999'; done
== /u01/app/oracle/oradata/ORCL19U/redo01.log
0
== /u01/app/oracle/oradata/ORCL19U/redo02.log
0
== /u01/app/oracle/oradata/ORCL19U/redo03.log
1957

カレントのREDOログ(redo03)に1,957件。 SYSTEM・SYSAUX・UNDO・TEMPをすべて暗号化した後でも、暗号化していないユーザー表領域への書き込みはREDOに平文で流れます

対照として、暗号化表領域の表に同じ操作をすると——

SQL> INSERT INTO hr_secret_enc SELECT 20000+LEVEL, 'REDOENC-0720', '4599-9999-9999-9999'
  2    FROM dual CONNECT BY LEVEL <= 1000;

1000行が作成されました。

SQL> COMMIT;

コミットが完了しました。

SQL> !for f in /u01/app/oracle/oradata/ORCL19U/redo0*.log; do echo "== $f"; strings $f | grep -c -E 'REDOENC-0720|4599-9999'; done
== /u01/app/oracle/oradata/ORCL19U/redo01.log
0
== /u01/app/oracle/oradata/ORCL19U/redo02.log
0
== /u01/app/oracle/oradata/ORCL19U/redo03.log
0

全ファイル0件。 REDOへの書き込みも、UNDO・TEMPと同じくソースの表領域に従う——これで通り道(UNDO・TEMP・REDO)の実測がすべてそろいました。 公式ドキュメントにも、暗号化表領域のデータについて「UNDOログとREDOログのデータも保護されます」と明記されています(『Oracle Database Advanced Securityガイド』19c「透過的データ暗号化表領域暗号化の動作」)。

そして、ここが本記事で一番伝えたい設計上の分かれ目です。 REDOだけ、対策の選択肢が1つ少ないのです。

通り道書き先を暗号化して防ぐソースを暗号化して防ぐ
UNDOできる(前節で実測)できる
TEMPできる(前節で実測)できる
REDOできない(REDOログは表領域ではない)できる(唯一の対策

UNDO・TEMPは書き先側でも守れますが(前節)、REDOに平文を流さない方法は、ソースの表領域を暗号化すること以外にありません。 管理系の表領域をどれだけ固めても、機密(またはそのコピー)を置くユーザー表領域が暗号化されないまま残っていれば、更新のたびにREDOから漏れ続けます。 ARCHIVELOG運用であれば、アーカイブログはREDOのコピーなので、同じ平文がアーカイブとそのバックアップにも乗っていきます(本環境は検証用のNOARCHIVELOGのため、ここは実測でなく機構からの帰結です)。

本環境で USERS を暗号化せずに残せるのは、「機密データを置かない」前提があるからです。 その前提を運用で守り切れないなら——機密がどの表領域に書かれるか管理しきれないなら——ユーザー表領域も含めてすべて暗号化するのが答えです。新規分は ENCRYPT_NEW_TABLESPACES=ALWAYS、既存分は第3回のオンライン暗号化移行で対応できます。


よくある Q&A

Q1. AWRに記録されたSQLは保持期間切れでビュー(DBA_HIST_SQLTEXT)から見えなくなっていたのに、なぜディスクには平文が残っていたのですか?

保持期間切れなどの「削除」は論理的な削除で、ディスク上のブロックが消去されるわけではないためです。 上書きされるまで平文の断片は残り、strings のような直接参照で読めます。 「ビューで見えない=ディスクに無い」ではない、という点が退役ディスクの脅威につながります。

Q2. SYSTEM・SYSAUX のオンライン暗号化は、稼働中のDBで実行して大丈夫なのですか?

本検証ではオンライン(ENCRYPTION ONLINE)で、稼働したまま完了しました。 機構は第3回で行ったユーザー表領域のオンライン暗号化移行と同じです。 所要時間はアラートログの実測で、SYSTEM(1,360MB)が約52秒、SYSAUX(1,650MB)が約63秒でした(検証用VMでの値です。実時間はサイズとストレージ性能次第で伸びます)。 対象ファイルと同規模の空き領域が必要になる点だけ、事前に確認が必要です。

Q3. 暗号化した表領域を、元(暗号化前の状態)に戻せますか?

本連載では「完全に元へ戻す」手段は VMスナップショットへの復元としています(連載①の可逆性整理と同じ方針)。 実施前にスナップショットを取得してから作業しています。

Q4. SYSTEM・SYSAUXまで暗号化すれば、TDEだけで安心ですか?

いいえ。 「暗号化しても『見える』もの」の節のとおり、DB経由の認可アクセスには透過で、SQLインジェクションや権限の濫用は防げません。 守れるのはディスク・バックアップ・退役HDDの物理的な窃取に対する層です(連載①の脅威モデルと第2回「守れる範囲・守れない範囲」で整理したとおりです)。

Q5. 暗号化した表領域のデータは、UNDO・TEMPに書かれるときも自動で暗号化されるのに、UNDO・TEMP自体を暗号化する意味はあるのですか?

あります。 自動で暗号化されるのは「ソースの表領域が暗号化されている」データだけで、非暗号化表領域が1つでも混在していれば、そのデータのUNDO・TEMPは平文で残ります(第2回の実測)。 書き先を暗号化しておけばソースを問わず守られるため、混在環境の保険=多層防御になります(「UNDO・TEMPも暗号化する」の節)。 なおREDOは書き先を暗号化できないため、この保険が効きません——機密を置く表領域はソース側の暗号化が前提です(「管理系の表領域を暗号化しても、REDOログには平文が残る」の節)。

Q6. オンライン暗号化ではファイルが作り直されるそうですが、断片化は解消されますか?

されません。 オンライン暗号化は各ブロックを同じ位置のまま暗号化して新ファイルへコピーする変換で、再編成ではありません(ROWID=ファイル番号+ブロック番号が変わらないことが前提の機能です)。 エクステントの配置・空き領域・断片化はそのまま引き継がれます。 実測でも、SYSTEMのデータファイルは暗号化の前後で1,360MBのまま変わりませんでした。 断片化の解消が目的なら、ALTER TABLE MOVE などの再編成を別途行うことになります。


まとめ — SYSTEM・SYSAUX・UNDO・TEMP の暗号化を完遂した

  • 第2回で特定した「TDEが守らない場所」——統計(SYSTEM)とAWRのSQLテキスト(SYSAUX)——は、SYSTEM・SYSAUXの暗号化で防げることを実機で確認しました(strings | grep で SYSTEM 4件・SYSAUX 2件 → どちらも0件
  • AWRのビューから保持期間切れで消えた後も、ディスク上の平文は残っていました。「ビューから消える」と「ディスクから消える」は別です
  • 暗号化してもビュー経由では実値が見えます。バインド変数・ヒストグラム抑制は暗号化後も併用する多層防御です
  • UNDOは現用(アクティブ)のままオンライン暗号化できました(平文4,000件→変換後0件)。TEMPだけは変換できないため作り直して切替です。切替はDB既定の確認ALTER USER だけでは変わらない)と旧TEMPの削除までがセット——どちらも、やり残してもエラーは出ません
  • SYSTEM・SYSAUX・UNDO・TEMPをすべて暗号化した後でも、暗号化していないユーザー表領域への書き込みはREDOに平文で残ります(実測1,957件)。REDOだけは書き先を暗号化できないため、機密を置く表領域はソース側の暗号化が唯一の対策——管理系を固めて終わり、にはなりません

これで、機密データを置く領域はすべて暗号化された構成になりました。 ウォレットの運用——自動ログインの設定と、起動できなくなったときの切り分け——は、別記事「ORA-28365 で startup が MOUNT で停止する」で実機検証しています。