Oracle Blockchain Tableでデジタル証明書・署名を使ってみた話【Oracle Database 21c】

Digital Certification and Signature on Blockchain Table Blockchain Table

この記事は、 JPOUG Advent Calendar 2020 及び「Oracle Cloud Infrastructure Advent Calendar 2020その2」の15日目のエントリーです。
14日目はKenichi Miharaさんの記事『RDS for OracleSE でいろいろやってみた』でした。

本記事はOracle Database 21cの新機能であるBlockchain Tableに一歩踏み込んだ、デジタル証明書・署名を使ってみた話になります。

Oracle Blockchain Tableとは

先日ついにOracle Database 21cが正式版がリリースされました。その21cの新機能の一つが「Blockchain Table」です。

Blockchain Tableはブロックチェーンの技術、思想をRDB(リレーショナルデータベース)に取り込んだものになります。Blockchain Tableを一言で表すと「書き換え・削除ができない中央集権データベース」です。

過去の記事「Oracle CloudでOracle Database 20c(プレビュー)のBlockchain Tableを使ってみた話」でBlockchain Tableの特徴と基本的な操作を紹介したので、概要と基本的な使い方は過去記事をご覧ください。

Blockchain Tableのデジタル証明書・署名とは

Blockchain Tableには複数の隠しカラムが存在し、ハッシュ値やチェインID、シークエンス番号などが保存されています。これらはBlockchain Tableに保存されたデータが改ざんされていないか検証するためのものです。

これに加えてBlockchain TableではX.509証明書を利用したPKIベースの電子署名で署名することができます。

Blockchain Tableはビルトインされた暗号学的ハッシュによる行のチェーン化に加えて、PL/SQLパッケージによりPKI(X.509)証明書を登録しておき、行が追加された際にユーザー署名を付与することができます。これによりユーザーや管理者が他者になりすましたり、あるいは他の誰かが自分になりすましたのだと主張することができなくなる、否認防止の特性をもたせることができます。

https://orablogs-jp.blogspot.com/2020/02/native-blockchain-tables.html

上記にあるように署名を追加することで、データの改ざん耐性だけでなく、なりすまし防止、ユーザーの証明を含めたデータの完全性を保証することが可能となります。

Blockchain Tableに署名を追加するための手順は以下のとおりです。

  1. X.509デジタル証明書をDatabaseにBLOBとして追加
  2. Blockchain Tableの隠しカラムに署名を追加

それでは実際にデジタル証明書の登録と署名を追加していきます。

*本記事て使用しているOracle Databaseバージョンは過去に作成した、Oracle Cloud Infrastructure上のDBCS(Database Cloud Service)のOracle Database 20c(preview)を利用していますが、21cでも同様です。

デジタル証明書の作成と追加

Blockchain Tableの事前準備

今回利用するスキーマ、表は以下のようになっています。

  • スキーマ:miyacle
  • 表(Blockchain Table):EMP
-- miyacleユーザー作成
CREATE USER miyacle IDENTIFIED BY <password> DEFAULT TABLESPACE users TEMPORARY TABLESPACE temp;

-- miyacleユーザーに権限付与
GRANT DBA TO miyacle;
GRANT UNLIMITED TABLESPACE TO miyacle;

-- Blockchain Table EM作成
CREATE BLOCKCHAIN TABLE emp (emp_id NUMBER(10), emp_name VARCHAR2(20), salary NUMBER(20))
NO DROP UNTIL 31 DAYS IDLE
NO DELETE LOCKED
HASHING USING "SHA2_512" VERSION "v1";
	
-- データの挿入				 
INSERT INTO emp VALUES(1, 'miyacle1', 1000);
INSERT INTO emp VALUES(2, 'miyacle2', 2000);
INSERT INTO emp VALUES(3, 'miyacle3', 3000);
commit;

OpenSSLを利用してデジタル証明書の作成

初めにOpenSSLを利用してテスト用のデジタル証明書の作成を行います。

今回はOracleのDocumentを参考にしてるため、細かい設定はドキュメントに沿っていきます。*ドキュメントに沿ってデジタル証明書をder形式に変換していますが、csr形式でも問題ありません。

//秘密鍵の作成
> openssl genrsa -aes128 -out rsa.key 2048

//証明書署名要求(CSR)の作成
> openssl req -new -days 365 -key rsa.key -out cert.csr

//CSRから証明書の作成
> openssl x509 -in cert.csr -out cert.crt -req -signkey rsa.key -days 365

//der形式に変換 *必須ではない
> openssl x509 -inform pem -outform der -in cert.crt -out cert.der

デジタル証明書が作成されました。証明書のインストールをしておきます。

これでデジタル証明書の準備ができました。次にDatabaseに追加していきます。

デジタル証明書を置いておくディレクトリを作成し、そのディレクトリをターゲットとしたDirectory Objectを作成しておきます。今回は/home/oracle/certificatesというディレクトリにcert.derという証明書を配置しておきます。

/home/oracle/certificatesにcert_dirという名前でオブジェクトを作成します。

CREATE DIRECTORY cert_dir AS '/home/oracle/certificates';
Directory CERT_DIRは作成されました。

デジタル証明書の追加

次にPL/SQLのプロシージャDBMS_USER_CERTS.ADD_CERTIFICATEを使ってBLOBとしてデジタル証明書を追加します。

-- outputをオン
SET SERVEROUTPUT ON;

DECLARE
	file       BFILE;
	buffer     BLOB;
	amount     NUMBER := 32767;
	cert_guid  RAW(16);
BEGIN
	file := BFILENAME('CERT_DIR', 'cert.der');
	DBMS_LOB.FILEOPEN(file);
	DBMS_LOB.READ(file, amount, 1, buffer);
	DBMS_LOB.FILECLOSE(file);
	DBMS_USER_CERTS.ADD_CERTIFICATE(buffer, cert_guid);
	DBMS_OUTPUT.PUT_LINE('Certificate GUID = ' || cert_guid);
END;
/

Certificate GUID = <GUID>
PL/SQLプロシージャが正常に完了しました。

上記のPL/SQLでは最後にGUIDを出力するようにしています。ここで生成されたGUIDはデジタル署名をする際にも使用するので、メモを取っておきます。以降本記事では<GUID>と表記します。

登録したデジタル証明書を確認します。

SELECT user_name, distinguished_name, UTL_RAW.LENGTH('<GUID>') CERT_GUID_LEN, DBMS_LOB.GETLENGTH(certificate) CERT_LEN FROM DBA_CERTIFICATES ORDER BY user_name;

USER_NAME DISTINGUISH_NAME CERT_GUID_LEN CERT_LEN
--------- ---------------- ------------- ---------
MIYACLE	  EMAIL=NA,CN=Miya,OU=NA,O=NA,L=Aoyama,ST=Tokyo,C=JP	16	606

デジタル証明書が追加されたことを確認できました。

デジタル署名の作成と追加

デジタル証明書がDatabaseに追加できたので、これを使用してBlockchain Tableの行に署名を行っていきます。デジタル署名の追加手順は以下のとおりです。

  1. Blockchain Tableに含まれるレコードのバイトを使用して署名ファイルを作成
  2. OpenSSL(データベースの外)を使用して署名を作成
  3. Blockchain Tableに署名の追加

デジタル署名の作成

今回署名ファイルは/home/oracle/signaturesというディレクトリに保存します。証明書の時と同様Directory Objectをsign_dirという名前で作成しておきます。

PL/SQLプロシージャを使って、Blockchain Tableに含まれるレコードのバイトから署名を作成します。プロシージャに関してはこちらのドキュメントに詳しく記載されています。

CREATE DIRECTORY sign_dir AS '/home/oracle/signatures';
Directory SIGN_DIRは作成されました。

DECLARE
  row_data        BLOB;
  buffer          RAW(4000);
  inst_id         BINARY_INTEGER;
  chain_id        BINARY_INTEGER;
  sequence_no     BINARY_INTEGER;
  row_len         BINARY_INTEGER;
  l_file          UTL_FILE.FILE_TYPE;
BEGIN
    SELECT ORABCTAB_INST_ID$, ORABCTAB_CHAIN_ID$, ORABCTAB_SEQ_NUM$
      INTO inst_id, chain_id, sequence_no FROM emp  where emp_id=3;
    DBMS_BLOCKCHAIN_TABLE.GET_BYTES_FOR_ROW_SIGNATURE ('MIYACLE','EMP', inst_id,chain_id, sequence_no, 1, row_data);
    row_len := DBMS_LOB.GETLENGTH(row_data);
    DBMS_LOB.READ(row_data, row_len, 1, buffer);
    l_file := UTL_FILE.fopen('SIGN_DIR','signature3.dat','wb', 32767);
    UTL_FILE.put_raw(l_file, buffer, TRUE);
    UTL_FILE.fclose(l_file);
END;
/

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

emp_id=3の行を対象にsignature3.datという署名ファイルを作成しました。/home/oracle/signaturesディレクトリの下にsignature3.datファイルが生成されました。

このsignature3.datを使ってOpenSSLより署名を作成します。署名をsign3.datという名前で出力します。ハッシュアルゴリズムはsha512を使用しました。

> openssl dgst -sha512 -sign rsa.key -out sign3.dat signature3.dat

デジタル署名の追加

デジタル署名が作成できたので、PL/SQLプロシージャDBMS_BLOCKCHAIN_TABLE.SIGN_ROWを使ってBlockchain Tableに追加していきます。

事前に先ほど作成したsign3.datを/home/oracle/signaturesディレクトリに配置します。

先ほどemp_id=3の行に対してデジタル署名を作成したので、emp_id=3の行に署名を追加します。署名を作成した際にsha512アルゴリズムを使用したのでDBMS_BLOCKCHAIN_TABLE.SIGN_ALGO_RSA_SHA2_512を指定します。

DECLARE
        file BFILE;
        amount NUMBER := 2000;
        inst_id binary_integer;
        chain_id binary_integer;
        sequence_no binary_integer;
        signature RAW(2000);
        cert_guid RAW (16) := HEXTORAW('<GUID>');
BEGIN
        SELECT ORABCTAB_INST_ID$, ORABCTAB_CHAIN_ID$, ORABCTAB_SEQ_NUM$ INTO inst_id, chain_id, sequence_no FROM emp WHERE emp_id = 3;
        file := bfilename('SIGN_DIR', 'sign3.dat');
        DBMS_LOB.FILEOPEN(file);
        dbms_lob.READ(file, amount, 1, signature);
        dbms_lob.FILECLOSE(file);
        DBMS_BLOCKCHAIN_TABLE.SIGN_ROW('MIYACLE','EMP', inst_id, chain_id, sequence_no, NULL, signature, cert_guid, DBMS_BLOCKCHAIN_TABLE.SIGN_ALGO_RSA_SHA2_512);
END;
/

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

違う行を指定して署名を追加しようとすると、以下のようにエラー(ORA-05757)となります。例:行3(emp_id=3)で作成した署名を行1(emp_id=1)に追加

エラー・レポート -
ORA-05757: signature verification failed for row at instance ID '1', chain ID '28', sequence number '1'
ORA-06512: "SYS.DBMS_BLOCKCHAIN_TABLE", 行720
ORA-06512: "SYS.DBMS_BLOCKCHAIN_TABLE", 行787
ORA-06512: 行16

隠しカラムを表示して、署名が追加されたか確認してみます。

SELECT ORABCTAB_INST_ID$,ORABCTAB_CHAIN_ID$,ORABCTAB_SEQ_NUM$,ORABCTAB_CREATION_TIME$,
ORABCTAB_USER_NUMBER$,ORABCTAB_HASH$,ORABCTAB_SIGNATURE$,ORABCTAB_SIGNATURE_ALG$,
ORABCTAB_SIGNATURE_CERT$ FROM emp;

1	28	1	20-12-01 12:54:37.360893000 GMT	113	059AF0CCE46C1359FC645789A25B7494D4E899944C7A0C4071F8F3E2DC93AD07BB648B5F7FB4AC478610F4CC4257A0E9CC3518A8C6AD64313BBDAD5C9FE30C65				
1	28	2	20-12-01 12:54:37.367131000 GMT	113	483C8FAEE9C08641A590CF93073D2C601CB219EC177EFAB29FE32878D89FFB9CDD18C21995E3A5BBAC9F9133D70E2A949908E30DF054EBBDDC253A4B101748EE							
1	17	1	20-12-12 09:25:02.986557000 GMT	113	E2C8FC68997C3F632BF9B2EB777A9CBA0B14333B7723384BAEBFC3615B6CD544564EB8B962A5F028C56E8A7560EABF5A391AEF016D33E40F3773AD7E5AAD3D28	89AA80DA0D2F671C478B1A1A3F9869EA704FAB5D9AB3CCAE669CBA5840CC27BE380F75CA06262BC3F4598506A8A7B29A027CD0BF76AD135E5B08064F65C2D33421FA8D0BD4C6AAE0510765A1FC961D9B7483C6CDAED2E27FE4F3D4FC5BA5AB1299B533F5847F4544432C73BD7EFAC698F8166DA1EF4B6B6B6CADDC2A37FF5A01	3	<GUID>				

少々見づらいですが、3つ目の行だけ以下の隠しカラムに署名データが追加されています。ORABCTAB_SIGNATURE$,ORABCTAB_SIGNATURE_ALG$,
ORABCTAB_SIGNATURE_CERT$

これでBlockchain Tableに署名を追加することができました。

Oracle Autonomous Databaseで21c/Blockchain Tableの利用

Oracle Blockchain TableはOracle Database 21cの新機能です。

Oracle Cloud Infrastructure上のDBCS(Database Cloud Service)ではOracle Database 21cが公式リリースとなり利用可能となりました。今回の記事でもDBCSを使用しました。

今回の検証では行っていませんが、Oracle Autonomous Databaseでも21cが利用できます。しかし、2020年12月15日現在、Autonomous Databaseでの21cの利用はAlways Free環境のみとなっております。

さらに、Always FreeでAutonomous Databaseを試す場合、Home Regionに絞られます。Home Regionが IAD, PHX, LHR, FRA の場合はそのままで、東京/大阪の場合は、別途フリーのテナントを上記4Regionsに立てることで利用可能となります。

*Autonomous DatabaseのATPにて21cを作成して、Blockchain Tableを無事作成できました。

おわりに

今回はOracle Database 21c(20c preview)の新機能Blockchain Tableでデジタル証明書の追加とデジタル署名の追加を行いました。

デジタル証明書とデジタル署名の準備ができれば簡単にBlockchain Tableへの追加が可能です。今後Autonomous Databaseでも試してみたいと思います。

Oracle Database 21cが利用できるようになってからまだ間もないですが、今後様々なユーザーの方に利用していただき、Blockchain Tableの利用が増えていくことが楽しみです。

引き続きBlockchain Tableの使ってみたレビューやユースケースの考察等も行っていきたいと思います。

最後までご覧いただきありがとうございました。

コメント

タイトルとURLをコピーしました