Oracle Database 21cより、RSA暗号が提供されています。以前にOracle DatabaseのJavaの実装を使ってJSON WebアルゴリズムのRSASSA-PKCS1-v1_5(RS256)に対応する方法を記事にしましたが、Autonomous DatabaseのようなJavaが使えない構成では不可ですし、パフォーマンス面での懸念もありました。
21cから、DBMS_CRYPTOのPKENCRYPT/PKDECRYPTによるRSA公開鍵暗号による暗号化/復号化、および、SIGN/VERIFYによる署名/検証を行うことができます。マニュアルの記載はこちらです。
動作確認と勉強を兼ねて、マニュアルの例題を動かしてみました。
まず、公開鍵/秘密鍵のペアを生成します。opensslを使った鍵の生成方法は、例題のコメントに記載されています。
最初に鍵長が2048ビットの秘密鍵を生成します。
openssl genrsa -out private.pem 2048
続いて、生成した秘密鍵より公開鍵を、PEM形式で取り出します。
openssl rsa -in private.pem -outform PEM -pubout -out public.pem
以前の記事でも紹介しましたが、生成されている秘密鍵と公開鍵をシェル・スクリプトを使って1行にしました。
#!/bin/sh while read l do test ${l:0:1} != "-" && /bin/echo -n $l done < private.pem echo
公開鍵を1行にするときは、private.pemの代わりに、public.pemを指定します。
マニュアルにあるExample 2: PKENCRYPTION and PKDECRYPTION Functionsを実行します。ファンクション名は正しくは、PKENCRYPTとPKDECRYPTです。例題のコードに含まれるファンクション名は正しいのですが、以下の2行でのシングル・クオートが正しくありません。
シングル・クオートも含めて、正しくXXXXを公開鍵、YYYYを秘密鍵に置き換えます。
pubkey VARCHAR (2000) := ‘XXXX’; prvkey VARCHAR (2000) := ‘YYYY’;
DECLARE ip_str VARCHAR (200) := 'Secret Message'; op_str VARCHAR (200); -- Use OpenSSL to generate the private and public key (2048 bit RSA key) -- openssl genrsa -out private.pem 2048 -- openssl rsa -in private.pem -outform PEM -pubout -out public.pem pubkey VARCHAR (2000) := 'ここに1行にしたpublic.pemの内容を含める'; prvkey VARCHAR (2000) := 'ここに1行にしたprivate.pemの内容を含める'; enc_raw RAW (2000); dec_raw RAW (2000); eType PLS_INTEGER := DBMS_CRYPTO.PKENCRYPT_RSA_PKCS1_OAEP; kType PLS_INTEGER := DBMS_CRYPTO.KEY_TYPE_RSA; BEGIN DBMS_OUTPUT.PUT_LINE('-------------------------------------------------'); DBMS_OUTPUT.PUT_LINE('Original String := ' || ip_str); DBMS_OUTPUT.PUT_LINE('-------------------------------------------------'); enc_raw:= DBMS_CRYPTO.PKENCRYPT ( src => UTL_I18N.STRING_TO_RAW(ip_str,'AL32UTF8'), pub_key => UTL_I18N.STRING_TO_RAW( pubkey, 'AL32UTF8'), pubkey_alg => kType, enc_alg => eType ); dec_raw := DBMS_CRYPTO.PKDECRYPT ( src => enc_raw, prv_key => UTL_I18N.STRING_TO_RAW( prvkey, 'AL32UTF8'), pubkey_alg => kType, enc_alg => eType ); op_str := UTL_I18N.RAW_TO_CHAR(dec_raw,'AL32UTF8'); dbms_output.put_line('-------------------------------------------------'); dbms_output.put_line('Decrypted String := ' || op_str); dbms_output.put_line('-------------------------------------------------'); end; /
実行した結果は以下になります。
------------------------------------------------- Original String := Secret Message ------------------------------------------------- ------------------------------------------------- Decrypted String := Secret Message ------------------------------------------------- PL/SQL procedure successfully completed. Elapsed: 00:00:00.006
次にExample 3: SIGN and VERIFY Functionsを試してみます。鍵の置き換えの注意点はPKENCRYPT/PKDECRYPTと同様です。DECLARE ip_str VARCHAR2 (200) := 'Secret Message'; -- Use OpenSSL to generate the private and public key (2048 bit RSA key) -- openssl genrsa -out private.pem 2048 -- openssl rsa -in private.pem -outform PEM -pubout -out public.pem pubkey VARCHAR (2000) := 'ここに1行にしたpublic.pemの内容を含める'; prvkey VARCHAR (2000) := 'ここに1行にしたprivate.pemの内容を含める'; sign_raw RAW (2000); returnval BOOLEAN := false; sType PLS_INTEGER := DBMS_CRYPTO.SIGN_SHA224_RSA; kType PLS_INTEGER := DBMS_CRYPTO.KEY_TYPE_RSA; BEGIN sign_raw := DBMS_CRYPTO.SIGN ( src => UTL_I18N.STRING_TO_RAW(ip_str,'AL32UTF8'), prv_key => UTL_I18N.STRING_TO_RAW( prvkey, 'AL32UTF8'), pubkey_alg => kType, sign_alg => sType ); returnval := DBMS_CRYPTO.VERIFY ( src => UTL_I18N.STRING_TO_RAW( ip_str,'AL32UTF8'), sign => sign_raw, pub_key => UTL_I18N.STRING_TO_RAW( pubkey, 'AL32UTF8'), pubkey_alg => kType, sign_alg => sType ); DBMS_OUTPUT.PUT_LINE('-------------------------------------------------'); IF returnval THEN DBMS_OUTPUT.PUT_LINE('True'); ELSE DBMS_OUTPUT.PUT_LINE('False'); END IF; DBMS_OUTPUT.PUT_LINE('-------------------------------------------------'); END; /
実行した結果は以下になります。
------------------------------------------------- True ------------------------------------------------- PL/SQL procedure successfully completed. Elapsed: 00:00:00.008
以上で、マニュアルの例題を用いた確認ができました。APEXでSAML認証をサポートしていないのはRSA公開鍵暗号方式が無いことが理由で、これが実装されたらサポートする方針と聞いているので、早く提供されることを期待しています。