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公開鍵暗号方式が無いことが理由で、これが実装されたらサポートする方針と聞いているので、早く提供されることを期待しています。