Oracle Database 12cR1で既存表領域のオフライン暗号化を試してみた

12cR1には平文の表領域を後で暗号化する機能があります。
もともと12cR2で追加された新機能でしたが、12cR1にもバックポートされました。
ただし利用するには下記MOSドキュメントにある個別パッチを適用する必要があります。

[Enable Transparent Data Encryption (TDE) Using Fast Offline Conversion in 11.2.0.4 and 12.1.0.2 （ドキュメントID 2148746.1）](https://support.oracle.com/epmos/faces/DocumentDisplay?id=2148746.1)

また12cR1における既存表領域の暗号化には以下の留意点があります。

+ 表領域をオフラインにする必要がある
+ ｢ALTER DATABASE DATAFILE ...」のDDLのみ使える（「ALTER TABLESPACE ... ENCRYPT;」は利用不可）
+ 暗号化アルゴリズムは AES128 のみ利用可

ちなみに12cR1は2022年8月から Sustaining Support に入りますのでご注意ください。

以降は本機能を試した際のログになります。
手順概要は以下の通りです。

**前提**
+ DBバージョン：12.1.0.2.0（個別パッチ p23315889 適用済み）
+ DB構成：シングルインスタンス（CDBとPDB構成済み）

**手順**
1. CDBにwalletを作成して暗号化キーを作成
2. PDBに平文の表領域を作成してサンプルデータを追加
3. PDBに暗号化キーを作成
4. 平文の表領域をオフライン暗号化

## 検証ログ

### CDBにwalletを作成して暗号化キーを作成

```
# walletを配置するディレクトリを作成
$ mkdir -p /u01/app/oracle/admin/orcl1/wallet

# walletを作成してオープン
$ sqlplus / as sysdba
SQL> ADMINISTER KEY MANAGEMENT CREATE KEYSTORE '/u01/app/oracle/admin/orcl1/wallet' IDENTIFIED BY <your password>;
SQL> ADMINISTER KEY MANAGEMENT SET KEYSTORE OPEN IDENTIFIED BY password CONTAINER=ALL;

# CDBに暗号化キーを作成
SQL> ADMINISTER KEY MANAGEMENT SET KEY USING TAG 'CDBKEY' IDENTIFIED BY <your password> WITH BACKUP USING 'BK_CDBKEY';

# 自動ログインを有効化
SQL> ADMINISTER KEY MANAGEMENT SET KEYSTORE CLOSE IDENTIFIED BY <your password>;
SQL> ADMINISTER KEY MANAGEMENT CREATE AUTO_LOGIN KEYSTORE FROM KEYSTORE '/u01/app/oracle/admin/orcl1/wallet' IDENTIFIED BY <your password>;
```

### PDBに平文の表領域を作成してサンプルデータを追加

```
# 接続先をPDBに変更
SQL> alter session set container=pdb1;

# 表領域を作成
SQL> CREATE TABLESPACE tsttbs1 DATAFILE '/u01/app/oracle/oradata/orcl1/pdb1/tsttbs1.dbf' SIZE 5M
   EXTENT MANAGEMENT LOCAL
   SEGMENT SPACE MANAGEMENT AUTO;

# 検証用ユーザを作成
SQL> create user tstusr identified by tstusr;
SQL> grant dba to tstusr;
SQL> alter user tstusr default tablespace tsttbs1;

# 検証用ユーザでDBにログイン
$ sqlplus tstusr/tstusr@<host fqdn>:1521/pdb1

# 検証用テーブルの作成とデータ追加
SQL> create table test_easy(col1 number, col2 number, col3 varchar2(20));

SQL> begin
     for i in 1..10000 loop
     insert into test_easy values(i, mod(i,5), 'dummy');
     end loop;
     end;
     /
```

### PDBに暗号化キーを作成

```
# 以降を実行する前に、事前に自動ログインwallet「cwallet.sso」を別ディレクトリに移動してください

# sysユーザでDBにログイン
$ sqlplus / as sysdba

# 一度walletをクローズしてパスワードでオープン
SQL> ADMINISTER KEY MANAGEMENT SET KEYSTORE CLOSE;
SQL> ADMINISTER KEY MANAGEMENT SET KEYSTORE OPEN IDENTIFIED BY <your password> CONTAINER=ALL;

# 接続先をPDBに変更
SQL> alter session set container=pdb1;

# PDB用の暗号化キーを作成
SQL> ADMINISTER KEY MANAGEMENT SET KEY USING TAG 'PDB1KEY' IDENTIFIED BY <your password> WITH BACKUP USING 'BK_PDB1KEY';

# 接続先をrootコンテナに変更
SQL> alter session set container=cdb$root;

# 自動ログインを有効化
SQL> ADMINISTER KEY MANAGEMENT SET KEYSTORE CLOSE IDENTIFIED BY <your password>;
SQL> ADMINISTER KEY MANAGEMENT CREATE AUTO_LOGIN KEYSTORE FROM KEYSTORE '/u01/app/oracle/admin/orcl2/wallet' IDENTIFIED BY <your password>;
```

### 平文の表領域をオフライン暗号化

```
# 暗号化されていないことを確認
SQL> select TABLESPACE_NAME, ENCRYPTED from DBA_TABLESPACES where TABLESPACE_NAME='tsttbs1';

# 対象の表領域をオフライン化
SQL> ALTER TABLESPACE tsttbs1 OFFLINE NORMAL; 

# 対象の表領域をオフライン暗号化
SQL> alter database datafile '/u01/app/oracle/oradata/orcl2/pdb3/tsttbs1.dbf' encrypt;

# 対象の表領域をオンライン化
SQL> ALTER TABLESPACE tsttbs1 ONLINE; 

# 暗号化されていることを確認
SQL> select TABLESPACE_NAME, ENCRYPTED from DBA_TABLESPACES where TABLESPACE_NAME='tsttbs1';
```

以上になります。