Oracleで暗号化に関する検証 その1
<Oracleで暗号化に関する検証 その1>
ペンネーム:ウィーット
今回から、Oracleを用いての暗号化について検証していきたいと思います。
個人情報保護法やSOX法などの策定が進んでいる中、企業におけるシステムの
セキュリティに注目が集まってきています。
DBにもセキュリティ機能が追加されていますが、Oracleで実現する暗号化につ
いて検証してみたいと思います。
まずは、Oracle10gR2 Enterprise Editionの新機能である「透過的なデータ暗
号化(Transparent Data Encryption 略してTDE)」について検証します。
TDEの特徴は以下の通りです。
・DB全体(Oracle)で共通鍵を生成・維持するため、ユーザーは鍵の管理を行わ
なくてよい
(OS上に鍵が作成されるため、その管理はユーザーが行わなくてはいけない)
・アプリケーションの変更なしで既存のテーブルに暗号化を行うことができる
・暗号化してある項目に索引をつけられる
新規テーブルに対して暗号化の項目を作成する手順と、既存のテーブルに暗号
化を行う手順を行ってみます。
まず準備として共通鍵の作成が必要です。
作成は、以下の手順で行います。
(1)sqlnet.oraに共通鍵の作成場所を指定する。
(2)リスナーを再起動する。
(3)SYSユーザーで鍵(Wallet)を作成する。
(4)dbms_crypto 権限を使用ユーザーに付与する。
テスト環境は以下の通りです。
Red Hat Enterprise Linux AS release 3 (Taroon Update 1)
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0
それでは始めましょう。
(1) sqlnet.oraに共通鍵の作成場所を指定します。
$ORACLE_HOME/network/admin/sqlnet.oraに共通鍵の場所を指定します。
ENCRYPTION_WALLET_LOCATION= (SOURCE=(METHOD=FILE)(METHOD_DATA= (DIRECTORY=/home/ora102/oracle/oracle/product/10.2.0/db_1))) ↑ 鍵を生成するディレクトリを指定
上記を指定しない場合は、以下のディレクトリ配下に作成されます。
$ORACLE_BASE/admin/$ORACLE_SID/wallet
(2) リスナーの再起動を行います。
(3) 鍵を生成します。
conn / as sysdba SQL> alter system set encryption key identified by "xxxxx";
「xxxxx」にパスワードを指定します。
鍵は、sqlnet.oraに指定したディレクトリに「ewallet.p12」という名前で作
成されます。
(4) dbms_crypto 権限を使用ユーザーに付与します。
SQL> grant execute on dbms_crypto to scott; Grant succeeded.
ようやく環境が整いました。フー!
TDEを使用する環境が整ったので、新規にテーブルを作成する場合と既存のテー
ブルに暗号化を行ってみます。
それでは、新規にテーブルを作成してみましょう。
テーブル名は「emp_encrypt」とします。
SQL> create table emp_encrypt ( empno number(4) not null, ename varchar2(10), job varchar2(9), mgr number(4), hiredate date, sal number(7,2) encrypt not null, comm number(7,2), deptno number(2) ) tablespace encrypt; 表が作成されました。
暗号化する項目に対して「encrypt」を指定します。
次に、暗号化している「sal」の項目に対してインデックスを作成してみましょう。
**********************************************************************
SQL> create index idx_emp_encrypt on scott.emp_encrypt (sal); create index idx_emp_encrypt on scott.emp_encrypt (sal) * 行1でエラーが発生しました。: ORA-28338: 索引付けされた列は、saltを使用して暗号化できません
**********************************************************************
お、エラーが出力されました。saltというのは乱数を生成して暗号化対象のデー
タを一定のビット長に補正(パディング)し、暗号化を行えるようにする機能で
す。暗号化の単位となるブロック長に満たない場合は、一定以上の長さを持つ
乱数で補正をしているようです。
この乱数(salt)指定があるとインデックスの作成が出来ないようです。
暗号化をする際に、乱数を付加されないように変更してみます。
新規に作成する時には、「no salt」オプションとして再度作成してみましょう。
**********************************************************************
SQL> create table emp_encrypt ( empno number(4) not null, ename varchar2(10), job varchar2(9), mgr number(4), hiredate date, sal number(7,2) encrypt no salt not null, comm number(7,2), deptno number(2) ) tablespace encrypt; 2 3 4 5 6 7 8 9 10 表が作成されました。 SQL> create index idx_emp_encrypt on scott.emp_encrypt (sal); 索引が作成されました。
**********************************************************************
既存のテーブルへの暗号化は以下のコマンドで実行します。
**********************************************************************
alter table 対象テーブル名(項目名 encyrpt); <—- インデックスを作
成しない場合
alter table 対象テーブル名(項目名 encrypt no salt); <—- インデックス
を作成または
既存する場合
**********************************************************************
既にインデックスがあり、no saltオプションを指定しない場合、以下のエラー
が出力されます。
**********************************************************************
行1でエラーが発生しました。:
ORA-28338: 索引付けされた列は、saltを使用して暗号化できません
**********************************************************************
乱数(salt)オプションについては、USER_ENCRYPTED_COLUMNSビューのSALの項目
を参照します。
**********************************************************************
SQL> select * from USER_ENCRYPTED_COLUMNS where TABLE_NAME='EMP_ENCRYPT'; TABLE_NAME COLUMN_NAME ENCRYPTION_ALG SAL ------------------------- ------------------------- ------------------------ --- EMP_ENCRYPT SAL AES 192 bits key YES
**********************************************************************
暗号化された項目に紐付けられたインデックスが本当に使用されているのか
SQL_TRACEから確認をしてみましょう。
**********************************************************************
SQL> select * from emp_encrypt where sal = 1600; ********************************************************************** このSQLの実行結果です。 ********************************************************************** 実行計画 ------- --------------------------------------------------- 0 SELECT STATEMENT MODE: ALL_ROWS 1 TABLE ACCESS MODE: ANALYZED (BY INDEX ROWID) OF 'EMP_ENCRYPT' (TABLE) 0 INDEX MODE: ANALYZED (RANGE SCAN) OF 'IDX_EMP_ENCRYPT' (INDEX)
**********************************************************************
インデックスが正しく使われていることがわかりました。
(統計情報の取得を行っております。)
鍵を使用停止(close)して、検索をしてみましょう。
**********************************************************************
SQL> conn / as sysdba 接続されました。 SQL> alter system set wallet close; システムが変更されました。 SQL> conn scott/tiger 接続されました。 SQL> select * from emp_encrypt where EMPNO = 7499; select * from emp_encrypt where EMPNO = 7499 * 行1でエラーが発生しました。: ORA-28365: ウォレットがオープンしていません
**********************************************************************
それでは、暗号化をしていない項目だけの検索は出来るでしょうか?
**********************************************************************
SQL> select EMPNO,ENAME,JOB,MGR,HIREDATE,COMM,DEPTNO from emp_encrypt 2 where empno = 7499; EMPNO ENAME JOB MGR HIREDATE COMM DEPTNO ------ ---------- --------- ---------- -------- ---------- ---------- 7499 ALLEN SALESMAN 7698 81-02-20 300 30
**********************************************************************
暗号化機能を使用するには、Walletをopenします。
**********************************************************************
SQL> conn / as sysdba 接続されました。 SQL> alter system set wallet open identified by "xxxxx"; システムが変更されました。 SQL> conn scott/tiger 接続されました。 SQL> select * from emp_encrypt where sal = 1600; EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ------ ---------- --------- ---------- -------- ---------- ---------- ---------- 7499 ALLEN SALESMAN 7698 81-02-20 1600 300 30
**********************************************************************
おおお、出来ました。
暗号化された項目の表示には、「Wallet」がOPENされていないと駄目なようで
す。
次週は、既存のテーブルに暗号化項目を追加したときのパフォーマンスの測定
とExport/Importについて検証をしてみたいと思います。
秋を実感しつつある茅ヶ崎にて