Autonomous Database：データを暗号化してエクスポートしたり、暗号化されたデータをインポートしたりしてみた

# はじめに
先日のAutonomous Databaseの機能アップデートで、DBMS_CLOUD.EXPORT_DATAプロシージャを使用してクラウド・ストレージにデータをエクスポートする際に、データを暗号化できるようになりました。

また、暗号化してエクスポートされたデータをDBMS_CLOUD.COPY_DATAプロシージャを使用して表にインポートしたり、DBMS_CLOUD.CREATE_EXTERNAL_TABLEプロシージャを使用して暗号化してエクスポートされたデータに対する外部表を作成できるようになりました。

記事執筆時点で対応しているファイルフォーマットはCSV、JSON、XMLの3種類です。
また、暗号化されたファイルの処理に対応しているプロシージャは記事執筆時点で以下の通りです。
・DBMS_CLOUD.COPY_DATA
・DBMS_CLOUD.CREATE_EXTERNAL_TABLE
・DBMS_CLOUD.CREATE_EXTERNAL_PART_TABLE
・DBMS_CLOUD.CREATE_HYBRID_PART_TABLE
・DBMS_CLOUD.COPY_COLLECTION
ただし、暗号化されたファイルのファイルサイズは4GB未満である必要があります。

ということで、早速試してみました。

# 1. エクスポートするデータの準備
Autonomous Databaseに接続します。
```
[opc@tools ~]$ sql admin/Demo#1Demo#1@adb


SQLcl: Release 23.3 Production on Wed Mar 13 00:42:39 2024

Copyright (c) 1982, 2024, Oracle.  All rights reserved.

Last Successful login time: Wed Mar 13 2024 00:42:48 +00:00

Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.23.0.1.0

SQL>
```
検証用のテーブルtest_tableを作成し、データをINSERTします。
```
SQL> CREATE TABLE test_table (
         id NUMBER,
         name VARCHAR2(100)
     );

Table TEST_TABLEは作成されました。

SQL> INSERT INTO test_table VALUES (1,'Michael');

1行挿入しました。

SQL> INSERT INTO test_table VALUES (2,'Bob');

1行挿入しました。

SQL> INSERT INTO test_table VALUES (3,'Steven');

1行挿入しました。

SQL> COMMIT;

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

SQL>
```
test_tableの内容を確認します。
```
SQL> SELECT * FROM test_table_imported;

   ID NAME       
_____ __________ 
    1 Michael    
    2 Bob        
    3 Steven     

SQL>
```

# 2. リソース・プリンシパルの有効化

DBMS_CLOUD_ADMIN.ENABLE_RESOURCE_PRINCIPALプロシージャを使用して、リソース・プリンシパルを有効化します。
```
SQL> EXEC DBMS_CLOUD_ADMIN.ENABLE_RESOURCE_PRINCIPAL();

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

SQL>
```

# 3. 暗号化キーを保存するクレデンシャルの作成
DBMS_CLOUD.CREATE_CREDENTIALプロシージャを使用して、暗号化キーを保存するクレデンシャルを作成します。
ここでは、CRED_FOR_ENCRYPTIONという名前のクレデンシャルを作成します。
passwordには使用する暗号化方式に適した暗号化キーを指定します。
usernameは任意の文字列でOKです。

```
SQL> BEGIN
         DBMS_CLOUD.CREATE_CREDENTIAL (
             credential_name => 'CRED_FOR_ENCRYPTION',
             username        => 'Any_username',
             password        => 'uPFJ2zQZ9yXTTDV9pNhHuG5asxU7rqA1'
         );
     END;
     /

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

SQL>
```
# 4. 暗号化を使用したエクスポートの実行
DBMS_CLOUD.EXPORT_DATAプロシージャを使用して、Object Storageへのデータのエクスポートを実行します。
暗号化に関する指定はformatオプションのencryptionに指定します。
typeに暗号化方式、credential_nameに暗号化キーを格納したクレデンシャルを指定します。
ここでは、
・DBMS_CRYPTO.ENCRYPT_AES256で暗号化アルゴリズムにAES256
・DBMS_CRYPTO.CHAIN_CBCでブロック暗号連鎖に暗号ブロック連鎖
・DBMS_CRYPTO.PAD_PKCS5でブロック暗号パディングにPKCS#5
を指定し、暗号化キーを格納したクレデンシャルとしてcred_for_encryptionを指定しています。
```
SQL> BEGIN
         DBMS_CLOUD.EXPORT_DATA (
             credential_name => 'OCI$RESOURCE_PRINCIPAL',
             file_uri_list   => 'https://objectstorage.ap-tokyo-1.oraclecloud.com/n/<namespace>/b/ExportBucket/o/encrypted.csv',
             query           => 'SELECT * FROM test_table',
             format          => json_object(
                                    'type' value 'csv',
                                    'encryption' value  json_object(
                                                            'type' value DBMS_CRYPTO.ENCRYPT_AES256 + DBMS_CRYPTO.CHAIN_CBC + DBMS_CRYPTO.PAD_PKCS5, 
                                                            'credential_name' value 'CRED_FOR_ENCRYPTION'
                                                        )
                                )
         );
     END;
     /

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

SQL>
```
file_uri_listで指定したバケットの内容を確認してみます。
![スクリーンショット 2024-03-13 10.40.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/93eee72b-9c76-fe42-3309-2ba69cc8561b.png)

encryptedを接頭辞にもつCSVファイルが作成されていることが確認できます。

作成されたCSVファイルをダウンロードして、テキストエディタで内容を確認してみます。

![スクリーンショット 2024-03-13 10.47.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/526de08b-446a-8c10-9613-cf2761a6f9e7.png)
ファイルの内容が暗号化されていることが確認できました。

# 5. 暗号化を使用してエクスポートしたCSVファイルのインポート

CSVファイルのインポート先となるテーブルtest_table_importedを作成します。
```
SQL> CREATE TABLE test_table_imported (
         id NUMBER,
         name VARCHAR2(100)
     );

Table TEST_TABLE_IMPORTEDは作成されました。

SQL>
```
DBMS_CLOUD.COPY_DATAプロシージャを使用して、Object Storageにある暗号化されたCSVファイルのインポートを実行します。
エクスポート実行時と同様に、暗号化に関する指定はformatオプションのencryptionに指定します。
typeに暗号化方式、credential_nameに暗号化キーを格納したクレデンシャルを指定します。
ここでは、
・DBMS_CRYPTO.ENCRYPT_AES256で暗号化アルゴリズムにAES256
・DBMS_CRYPTO.CHAIN_CBCでブロック暗号連鎖に暗号ブロック連鎖
・DBMS_CRYPTO.PAD_PKCS5でブロック暗号パディングにPKCS#5
を指定し、暗号化キーを格納したクレデンシャルとしてcred_for_encryptionを指定しています。
```
SQL> BEGIN
        DBMS_CLOUD.COPY_DATA (
            table_name       => 'test_table_imported',
            credential_name  => 'OCI$RESOURCE_PRINCIPAL',
            file_uri_list    => 'https://objectstorage.ap-tokyo-1.oraclecloud.com/n/nrhnlrqdttaw/b/ExportBucket/o/encrypted*.csv',
            format           => json_object( 
                                    'type' value 'csv', 
                                    'encryption' value json_object(
                                                           'type' value DBMS_CRYPTO.ENCRYPT_AES256 + DBMS_CRYPTO.CHAIN_CBC + DBMS_CRYPTO.PAD_PKCS5,
                                                           'credential_name' value 'CRED_FOR_ENCRYPTION'
                                                       )
                                )
         );
     END;
     /

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

SQL>
```
test_table_importedの内容を確認します。
```
SQL> SELECT * FROM test_table_imported;

   ID NAME       
_____ __________ 
    1 Michael    
    2 Bob        
    3 Steven     

SQL>
```
Object Storageにある暗号化されたCSVファイルのデータが正しくインポートできたことが確認できました。


# 6. 暗号化を使用してエクスポートしたCSVファイルに対する外部表の作成
DBMS_CLOUD.CREATE_EXTERNAL_TABLEプロシージャを使用して、Object Storageにある暗号化されたCSVファイルに対して外部表を作成します。
DBMS_CLOUD.COPY_DATAでデータをインポートする場合と同様に、外部表作成の場合も暗号化に関する指定はformatオプションのencryptionに指定します。
typeに暗号化方式、credential_nameに暗号化キーを格納したクレデンシャルを指定します。
ここでは、
・DBMS_CRYPTO.ENCRYPT_AES256で暗号化アルゴリズムにAES256
・DBMS_CRYPTO.CHAIN_CBCでブロック暗号連鎖に暗号ブロック連鎖
・DBMS_CRYPTO.PAD_PKCS5でブロック暗号パディングにPKCS#5
を指定し、暗号化キーを格納したクレデンシャルとしてcred_for_encryptionを指定しています。
```
SQL> BEGIN
         DBMS_CLOUD.CREATE_EXTERNAL_TABLE(
             table_name      =>'test_table_external',
             credential_name =>'OCI$RESOURCE_PRINCIPAL',
             file_uri_list   =>'https://objectstorage.ap-tokyo-1.oraclecloud.com/n/<nemespace>/b/ExportBucket/o/encrypted*.csv',
             format          => json_object( 
                                    'type' value 'csv',
                                    'delimiter' value ',',
                                    'encryption' value json_object(
                                                           'type' value DBMS_CRYPTO.ENCRYPT_AES256 + DBMS_CRYPTO.CHAIN_CBC + DBMS_CRYPTO.PAD_PKCS5,
                                                           'credential_name' value 'CRED_FOR_ENCRYPTION'
                                                       )
                                ),
             column_list => 'id NUMBER, NAME VARCHAR2(100)' );
     END;
     /

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

SQL> 
```
作成された外部表test_table_externalの内容を確認します。
```
SQL> SELECT * FROM test_table_external;

   ID NAME       
_____ __________ 
    1 Michael    
    2 Bob        
    3 Steven     

SQL>
```
Object Storageにある暗号化されたCSVファイルに対して外部表が作成でき、データに正しくアクセスできることが確認できました。

# 参考情報
・[Encrypt Data While Exporting or Decrypt Data While Importing](https://docs.oracle.com/en/cloud/paas/autonomous-database/serverless/adbsb/encrypt-decrypt-import-export-object-store.html#GUID-484627E6-8599-4BE6-A5A6-464AD2394459)
・[DBMS_CLOUD.CREATE_CREDENTIALプロシージャ](https://docs.oracle.com/cd//E83857_01/paas/autonomous-database/serverless/adbsb/dbms-cloud-subprograms.html#GUID-742FC365-AA09-48A8-922C-1987795CF36A)
・[DBMS_CRYPTO Algorithms](https://docs.oracle.com/en/database/oracle/oracle-database/19/arpls/DBMS_CRYPTO.html#GUID-CE3CF17D-E781-47CB-AEE7-19A9B2BCD3EC)
・[DBMS_CLOUD.EXPORT_DATAプロシージャ](https://docs.oracle.com/cd//E83857_01/paas/autonomous-database/serverless/adbsb/dbms-cloud-subprograms.html#GUID-F8A70BE2-6060-48A7-9667-0A6B39198071)
・[DBMS_CLOUD.COPY_DATAプロシージャ](https://docs.oracle.com/cd//E83857_01/paas/autonomous-database/serverless/adbsb/dbms-cloud-subprograms.html#GUID-9428EA51-5DDD-43C2-B1F5-CD348C156122)
・[DBMS_CLOUD.CREATE_EXTERNAL_TABLEプロシージャ](https://docs.oracle.com/cd//E83857_01/paas/autonomous-database/serverless/adbsb/dbms-cloud-subprograms.html#GUID-2AFBEFA4-992E-4F53-96DB-F560084C7DA9)