Oracle Databaseの新機能であり、高い耐改ざん性、監査性をもつOracle Blockchain Table。Insert Onlyかつハッシュチェーンを利用してデータの整合性を確認できるという特徴があります。
しかし、なんらかの手法でもしデータが改竄されてしまったらどんな動きになるのでしょうか、またどのように検知できるのでしょうか。今回はそれを検証してみたいと思います。
「Oracle Blockchain Tableとは何か」については過去の記事をご覧ください。
前提条件、環境
今回使用する環境はOracle Cloud Infrastructure(OCI)にcompute instanceを立て、そこにOracle Databaseをインストールしたものです。
Oracle Database、その他環境は過去記事の「Oracle Database 19cでOracle Blockchain Tableを利用するまでの準備」にて作成したものです。以下に改めて書いておきます。
- IaaS上にOracle Databaseをインストール(オンプレミス想定)
- OS Oracle Linux 7.9
- Oracle Database 19c EE (バージョン 19.10 + 個別パッチ32431413適用)*
- マルチテナント PDB構成
- 表領域暗号化無し
*2021年6月24日現在では19.11が最新バージョンです。19.11でもBlockchain Tableを利用できます。
事前準備(Blockchain Table作成、データ挿入)
まずBlockchain Table「bc_table」を作成します。col1、col2という列を含みます。
「col1」「col2」にそれぞれ「first name」「last name」として複数行追加し、コミットします。
--Blockchain Tableを作成
CREATE BLOCKCHAIN TABLE bc_table (col1 VARCHAR2(10), col2 VARCHAR2(10))
NO DROP UNTIL 5 DAYS IDLE
NO DELETE UNTIL 16 DAYS AFTER INSERT
HASHING USING "SHA2_512" VERSION "v1";
--データを挿入
INSERT INTO bc_table VALUES('SUZUKI','HIROSHI');
INSERT INTO bc_table VALUES('MAEDA','KEITA');
INSERT INTO bc_table VALUES('KATO','RYOKO');
INSERT INTO bc_table VALUES('YAMADA','TARO');
INSERT INTO bc_table VALUES('TANAKA','HANAKO');
COMMIT;
これで下準備はできました。
Blockchain Table内のデータを改ざん
次に直接表領域のデータブロックを操作し内容を変更します。
bc_table表のCOL2「HIROSHI」を「MIYACLE」に変更します。
--改ざん前
COL1 COL2 inst chain seq time user hash
------ ------ ---- ----- --- ------------------------------- ---- --------------------------------------------------------------------------------------------------------------------------------
SUZUKI HIROSHI 1 2 1 21-04-15 13:57:06.825744000 GMT 106 86813BDD6533781C5DAF84D12FCCBF5EC2641BB5F671A0EB4E03DE94E839F44A70B7F3154117F02EDCBB202AE0DECC8E654FC86E9F9A8E1B1F74911848FBAC72
MAEDA KEITA 1 2 2 21-04-15 13:57:06.828240000 GMT 106 C85006FE2A4678782CBEB01DC4ADCC2A5D2A1549456CF1CA83ECE37C63CF76C1EE206EF5D73D058C332F2D8C26841988EFECE9D929BCE652549D1288C2990502
KATO RYOKO 1 2 3 21-04-15 13:57:06.828475000 GMT 106 BEF8ADF66A0B06D7B09F13E1A1DCCD8B9FC14E339B717ACDD7E3AB234391B69FDA9F83EE7B996B03BF5268693013969B5130A56C8874C61FDEB3E82C1B49ED97
YAMADA TARO 1 26 1 21-04-15 03:03:59.460990000 GMT 106 8E5F438B32A44A551EA7238BDFD9070D8A71411D441EDA553823A663E55389E0C0BB8F2AB26B879447B5EF1A3A78843CEE9D6D7C5106905730BD5975340EFCC0
TANAKA HANAKO 1 26 2 21-04-15 03:03:59.463491000 GMT 106 4796D272421738B27DE1C2A4B9998B9627F5C0A0D73EFEBCA484E34E5A75CC037CFC698CD17C8A4B977A75F092D1051F0A1660031ECD4F24BFC730641ABB37EB
--改ざん後
SUZUKI MIYACLE 1 2 1 21-04-15 13:57:06.825744000 GMT 106 86813BDD6533781C5DAF84D12FCCBF5EC2641BB5F671A0EB4E03DE94E839F44A70B7F3154117F02EDCBB202AE0DECC8E654FC86E9F9A8E1B1F74911848FBAC72
MAEDA KEITA 1 2 2 21-04-15 13:57:06.828240000 GMT 106 C85006FE2A4678782CBEB01DC4ADCC2A5D2A1549456CF1CA83ECE37C63CF76C1EE206EF5D73D058C332F2D8C26841988EFECE9D929BCE652549D1288C2990502
KATO RYOKO 1 2 3 21-04-15 13:57:06.828475000 GMT 106 BEF8ADF66A0B06D7B09F13E1A1DCCD8B9FC14E339B717ACDD7E3AB234391B69FDA9F83EE7B996B03BF5268693013969B5130A56C8874C61FDEB3E82C1B49ED97
YAMADA TARO 1 26 1 21-04-15 03:03:59.460990000 GMT 106 8E5F438B32A44A551EA7238BDFD9070D8A71411D441EDA553823A663E55389E0C0BB8F2AB26B879447B5EF1A3A78843CEE9D6D7C5106905730BD5975340EFCC0
TANAKA HANAKO 1 26 2 21-04-15 03:03:59.463491000 GMT 106 4796D272421738B27DE1C2A4B9998B9627F5C0A0D73EFEBCA484E34E5A75CC037CFC698CD17C8A4B977A75F092D1051F0A1660031ECD4F24BFC730641ABB37EB
無事変更が確認できました。ここではcol2のみ変更され、ハッシュ値を含め他のカラムや隠しカラムは変更されていないことが確認できます。
これでデータが改ざんされたことになります。SELECT文でデータを取得した場合、変更後のデータが表示され改ざんに気づくことができません。
ここでさらに1行データを追加してみます。
--改ざん後にINSERT/COMMIT
COL1 COL2 inst chain seq time user hash
------ ------ ---- ----- --- ------------------------------- ---- --------------------------------------------------------------------------------------------------------------------------------
SUZUKI MIYACLE 1 2 1 21-04-15 13:57:06.825744000 GMT 106 86813BDD6533781C5DAF84D12FCCBF5EC2641BB5F671A0EB4E03DE94E839F44A70B7F3154117F02EDCBB202AE0DECC8E654FC86E9F9A8E1B1F74911848FBAC72
MAEDA KEITA 1 2 2 21-04-15 13:57:06.828240000 GMT 106 C85006FE2A4678782CBEB01DC4ADCC2A5D2A1549456CF1CA83ECE37C63CF76C1EE206EF5D73D058C332F2D8C26841988EFECE9D929BCE652549D1288C2990502
KATO RYOKO 1 2 3 21-04-15 13:57:06.828475000 GMT 106 BEF8ADF66A0B06D7B09F13E1A1DCCD8B9FC14E339B717ACDD7E3AB234391B69FDA9F83EE7B996B03BF5268693013969B5130A56C8874C61FDEB3E82C1B49ED97
AFTER MODIFY 1 4 1 21-04-15 14:30:01.095801000 GMT 106 FA841987E8785AB2E1AA6E34D294C369B619519135A61CFD24DC6875E4DCFACADEA96AE503F1E90D7E5D18A9D79B324A910BD6D2FC068EE892AA84B277FD2A0C
YAMADA TARO 1 26 1 21-04-15 03:03:59.460990000 GMT 106 8E5F438B32A44A551EA7238BDFD9070D8A71411D441EDA553823A663E55389E0C0BB8F2AB26B879447B5EF1A3A78843CEE9D6D7C5106905730BD5975340EFCC0
TANAKA HANAKO 1 26 2 21-04-15 03:03:59.463491000 GMT 106 4796D272421738B27DE1C2A4B9998B9627F5C0A0D73EFEBCA484E34E5A75CC037CFC698CD17C8A4B977A75F092D1051F0A1660031ECD4F24BFC730641ABB37EB
特に問題なくデータの追加ができました。改ざんされた行も表示されています。
データ(ハッシュ値)の検証
次に改ざんを「検知」できるか確認します。
Blockchain Tableの行を検証できるプロシージャ「DBMS_BLOCKCHAIN_TABLE.VERIFY_ROWS」を実行します。
DECLARE
verify_rows NUMBER;
BEGIN
DBMS_BLOCKCHAIN_TABLE.VERIFY_ROWS('miyacle','bc_table', NULL, NULL, NULL, NULL, verify_rows);
DBMS_OUTPUT.PUT_LINE('Number of rows verified = '|| verify_rows);
END;
行の検証を実行したところ以下のようなORA-05737というエラーがが発生しました。
//DBMS_BLOCKCHAIN_TABLE.VERIFY_ROWSを実行
次のコマンドの開始中にエラーが発生しました : 行 9 -
DECLARE
verify_rows NUMBER;
BEGIN
DBMS_BLOCKCHAIN_TABLE.VERIFY_ROWS('miyacle','bc_table', NULL, NULL, NULL, NULL, verify_rows);
DBMS_OUTPUT.PUT_LINE('Number of rows verified = '|| verify_rows);
END;
エラー・レポート -
ORA-05737: rows verification failed at instance ID '1', chain ID '2', sequence number '1'
ORA-06512: "SYS.DBMS_BLOCKCHAIN_TABLE", 行61
ORA-06512: "SYS.DBMS_BLOCKCHAIN_TABLE", 行162
ORA-06512: 行4
「ORA-05737: rows verification failed at instance ID ‘1’, chain ID ‘2’, sequence number ‘1’」とエラーが表示されました。Instance ID=1、chain ID=2 sequence number=1の行で検証が失敗したと出ています。改ざんされた行の隠しカラムを確認してみると改ざんした行は「Instance ID=1、chain ID=2 sequence number=1」であり、エラーの値と合致します。
COL1 COL2 inst chain seq time user hash
------ ------ ---- ----- --- ------------------------------- ---- --------------------------------------------------------------------------------------------------------------------------------
SUZUKI MIYACLE 1 2 1 21-04-15 13:57:06.825744000 GMT 106 86813BDD6533781C5DAF84D12FCCBF5EC2641BB5F671A0EB4E03DE94E839F44A70B7F3154117F02EDCBB202AE0DECC8E654FC86E9F9A8E1B1F74911848FBAC72
エラーの詳細を確認します(こちらのドキュメントの項目ORA-05737でも確認できます)。
//エラーの詳細を表示
>oerr ora 05737
5737, 00000, "rows verification failed at instance ID '%s', chain ID '%s', sequence number '%s'"
// *Cause: Rows of blockchain table were corrupted. Verification failed at
// the row specified by instance ID, chain ID and sequence number.
// *Action: No action required.
//
「Rows of blockchain table were corrupted」とあります。ブロックチェーンテーブルの行が破損していると書かれています。
無理やりBlockchain Tableのデータブロックを書き換えたので、検証の際にhashの整合性が取れなく行が破損してしまったと認識されているようです。
このように改ざんされたデータに対して検証プロシージャを実行すると、どの行が改ざん(破損)しているか検知できるようになっています。
結果・まとめ、考察
まとめです。以下の結果となりました。
- Blockchain Tableに対してSQLからデータの変更はできないためデータブロックを直接書き換え (BC_TABLEブロックチェーン表, COL2の’HIROSHI’を’MIYACLE’へ変更 )
- その後、SQLでSELECTしデータの書き換えを確認、さらにデータを追加
- DBMSパッケージ(DBMS_BLOCKCHAIN_TABLE.VERIFY_ROWSプロシージャ)で行の検証を実施
- ORAエラー(ORA-05737)が発生し、改ざんを検知
今回はデータブロックを直接書き換えるという手法でデータの改ざんを再現しました。データを1部書き換えましたが対象行のHASH値が変わることはありませんでした。また、他の隠しカラムにも影響は特にありませんでした。
検証結果として、改ざんされたデータに対して行の検証を行うとORAエラーが発生し、改ざんを検知することができました。
テーブルや行の見た目では改ざんされているか分かりませんが、DBMS_BLOCKCHAIN_TABLE.VERIFY_ROWSで検証することで検知できるということが改めて確認できました。
Blockchain TableやImmutable Table、ユーザのアクセス制御が可能なDatabase Vaultはどれも、データベース・アクセスの正当な権限ではデータの更新や変更を不可にする機能があります。しかし、今回のようにデータファイル上のビット列を直接書き換えられてしまうことを阻止する機能階層ではありません。
データを直接変更されてしまっても、ハッシュ値を検算することでそれを「検出」することができるというBlockchainの性質をOracle Blockchain Tableは持っています。
TDEで表領域暗号化を行っていれば直接データを書き換えられるリスクを減らすことができ、今回のような改ざんを防ぐことができます。Oracle Cloud Infrastructureで提供されているPaaSサービス(DBCS、Autonomous Databaseなど)ではデフォルトで表領域暗号化が実装されているため、安心して利用することができます。
今回の検証より、Oracle Blockchain Tableを利用する際は表領域の暗号化を利用するべきだと考えられます(もちろんBlockchain Tableを利用しない場合も暗号化を推奨します)。
おわりに
今回はOracle Blockchain Tableのデータが改ざんされたときの動きを確認しました。
今回の検証を通して感じたことは、セキュリティオプションや、セキュリティ関連製品、その他すべてのプログラムにも言えることですが、それがどの階層を対象とした、何を実現する機能なのかを理解した上で利用することが非常に大切であるということです。裏を返せば、それを理解せずに利用することで思わぬところで穴が見つかり想定外の事故を招きかねないということです。
最後までご覧いただきありがとうございました。
コメント