身近なところからはじめるセキュリティ対策 | データの暗号化と復号
Hi everyone ! This is “0780B8175FEA03CA7CFFA1BC91EF940F”.
昨今、何かとセキュリティ対策が騒がれていますが。PowerBuilder ユーザーの皆さん、アプリケーションの
「セキュリティ対策してますか?」
実は最近、サポートに Oracle を使ったデータの暗号化 / 復号って利用できますかーっていう問い合わせがちょいちょい来ています。今回は、そんな暗号化 / 復号する機能が PowerBuilder 2017 R3 に追加されましたよってハナシ。
Oracle を利用したデータの暗号化 / 復号
PowerBuilder 2017 R3 で追加された暗号化 / 復号について説明をする前に、比較検証を行うため Oracle を利用して暗号化 / 復号の確認をしてみます。
Oracle では、 “DBMS_CRYPTO” パッケージを利用して簡単に暗号化 / 復号することができるようです。暗号化には “DBMS_CRYPTO.ENCRYPT” ファンクションを、復号には “DBMS_CRYPTO.DECRYPT” ファンクションを使用するようです。
なお、 “DBMS_CRYPTO” パッケージの実行権限は SYS ユーザーにのみ付与されているため、このパッケージに収録されているプロシージャやファンクションを他ユーザーで利用したい場合には、事前に実行権限を付与しておく必要があります。
皆さん、権限は付与できましたか?
それでは、Oracle に接続して SQL 文を実行してみましょう。Web 上にも様々なサンプルコードや各種パラメーターの設定情報が掲載されていますので SQL 文作成時の参考にしてみてください。今回は、下記サンプル SQL 文を用意して実行してみます。
まずは、暗号化から。
SELECT DBMS_CRYPTO.ENCRYPT( SRC => UTL_I18N.STRING_TO_RAW ('玉子焼(たまごやき)','AL32UTF8'), TYP => 8 + 256 + 4096, KEY => UTL_I18N.STRING_TO_RAW(RPAD('mypassword',32,CHR(0)),'AL32UTF8')) "暗号化" FROM DUAL;
暗号化 -------------------------------------------------------------------------------- 36E443025247D361982C97D7211AEF118D648136049BB5ADE7EDF64EC4DBBDEB
次に、暗号化されたデータを復号してみます。
SELECT UTL_I18N.RAW_TO_CHAR( DBMS_CRYPTO.DECRYPT( SRC => '36E443025247D361982C97D7211AEF118D648136049BB5ADE7EDF64EC4DBBDEB', TYP => 8 + 256 + 4096, KEY => UTL_I18N.STRING_TO_RAW(RPAD('mypassword',32,CHR(0)),'AL32UTF8')) ,'AL32UTF8') "復号" FROM DUAL;
復号 -------------------------------------------------------------------------------- 玉子焼(たまごやき)
うん、なんで「玉子焼(たまごやき)」?っていうツッコミは置いといて。いい感じにデータが暗号化 / 復号されているのが確認できますね。
PowerBuilder を利用したデータの暗号化 / 復号
では、本題。PowerBuilder でデータの暗号化 / 復号を確認していきましょう。
PowerBuilder 2017 R3 では、暗号化 / 復号を行うため新たに CrypterObject オブジェクトが追加されました。データの暗号化には CrypterObject の “SymmetricEncrypt” 関数を、復号には “SymmetricDecrypt” 関数を使用します。
構文は以下の通り。
SymmetricEncrypt 関数
crypter.SymmetricEncrypt ( algorithm, variable, key{, operationmode{, iv{, padding}}})
SymmetricDecrypt 関数
crypter.SymmetricDecrypt ( algorithm, variable, key{, operationmode{, iv{, padding}}})
各引数の詳細については最近リリースされた日本語版ヘルプを確認して欲しいのですが、今回使用する引数について少しだけ解説します。
- algorithm
- 暗号化アルゴリズムを指定する。Oracle の “TYP” パラメーターで “8” を指定した箇所に該当し、この場合は “Advanced Encryption Standard” (AES) の暗号方式を使用する。PowerBuilder で同じ暗号方式を使用する場合は、 “AES!” をこの引数に指定する。
- operationmode
- ブロック暗号連鎖を指定する。Oracle の “TYP” パラメーターで “256” を指定した箇所に該当し、この場合は “Cipher Block Chaining mode” (CBC) のモードを使用する。PowerBuilder で同じモードを使用する場合は、 “OperationModeCBC!” をこの引数に指定する。
- padding
- ブロック暗号パディングを指定する。Oracle の “TYP” パラメーターで “4096” を指定した箇所に該当し、この場合は “Public-Key Cryptography Standards” (PKCS) でパディングする。PowerBuilder で同じパディングを指定する場合は、 “PKCSPadding!” をこの引数に指定する。
それでは早速使ってみましょう。
// 変数宣言 Blob Lb_data,Lb_key,Lb_iv,Lb_encrypt,Lb_decrypt CrypterObject lnv_CrypterObject // データを暗号化および復号 CoderObject lnv_CoderObject // データをエンコードまたはデコード // オブジェクト作成 lnv_CrypterObject = Create CrypterObject lnv_CoderObject = Create CoderObject // データとキーを格納 Lb_data = Blob("玉子焼(たまごやき)", EncodingUTF8!) Lb_key = Blob(Left('mypassword' + Fill('0',32),32), EncodingUTF8!) // SymmetricEncrypt 関数でデータ暗号化 Lb_encrypt = Lnv_CrypterObject.SymmetricEncrypt(AES!, Lb_data, Lb_key, OperationModeCBC!, Lb_iv, PKCSPadding!) // SymmetricDecrypt 関数でデータ復号 Lb_decrypt = lnv_CrypterObject.SymmetricDecrypt(AES!, Lb_encrypt, Lb_key, OperationModeCBC!, Lb_iv, PKCSPadding!) // 結果確認 MessageBox("SymmetricEncrypt", lnv_CoderObject.HexEncode(Lb_encrypt)) MessageBox("SymmetricDecrypt", String(Lb_decrypt, EncodingUTF8!))
メッセージボックスに表示された結果は以下の通り。
SymmetricEncrypt ⇒ 10BEF7F08E8243E3660FBAFE26D95551142FFDD6BA8AB77EF5AC8013DF65C028 SymmetricDecrypt ⇒ 玉子焼(たまごやき)
おぉー。想定通・・・ん・・・?
Why PowerBuilder !?
暗号化されたデータの戻り値が Oracle と異なるぞ。
KEY パラメーターが Oracle では Char(0) つまり Null で文字を埋めているんだよなぁ。でも PowerBuilder は、Null で埋めることができないから ‘0’ で埋めてみたけど・・・。う~む。
であれば、Oracle の Key を ‘0’ で埋めるように変更してみよう。そうすれば一致するはずだ!
SELECT
DBMS_CRYPTO.ENCRYPT(
SRC => UTL_I18N.STRING_TO_RAW ('玉子焼(たまごやき)','AL32UTF8'),
TYP => 8 + 256 + 4096,
KEY => UTL_I18N.STRING_TO_RAW(RPAD('mypassword', 32, '0'), 'AL32UTF8')) "暗号化"
FROM DUAL;
どうだ!
暗号化 -------------------------------------------------------------------------------- 29277876953CB3AA63ABA145F70372C412B4D1599BC1FB51CE6239F715970B88
・・・シーン。いやいやいやいや、話が違いますよ・・・。え、これ一致させることできないの?こうなったら、Appeon 社へ問い合わせてみよう。📨
回答は以下の通り。
Hi "0780B8175FEA03CA7CFFA1BC91EF940F"-san. ~~~ 以下は、日本語翻訳 ~~~ operationmode に CBC を使用する場合は、iv パラメーターを構成する必要があります。 PB の場合、iv パラメーターのデフォルトは 16 個 の 0 になり、Null はサポートされていません。 一方で Oracle は、Null をサポートしていてデフォルト値が Null になります。 この違いから、PB と Oracle の結果を一致させるには、SQL 文の iv パラメーターに 16 個 の 0 を設定してください。
ふむ、IV パラメーターのデフォルト値の違いですか。では、Oracle の SQL 文をもう少し変更して実行してみます。
SELECT DBMS_CRYPTO.ENCRYPT( SRC => UTL_I18N.STRING_TO_RAW ('玉子焼(たまごやき)','AL32UTF8'), TYP => 8 + 256 + 4096, KEY => UTL_I18N.STRING_TO_RAW(RPAD('mypassword', 32, '0'), 'AL32UTF8'), IV => UTL_I18N.STRING_TO_RAW('0000000000000000', 'AL32UTF8')) "暗号化" FROM DUAL;
暗号化 -------------------------------------------------------------------------------- 10BEF7F08E8243E3660FBAFE26D95551142FFDD6BA8AB77EF5AC8013DF65C028
キタ━━━(゚∀゚)━━━!!
念のため、復号も実行してみよう。
SELECT UTL_I18N.RAW_TO_CHAR (DBMS_CRYPTO.DECRYPT( SRC => '10BEF7F08E8243E3660FBAFE26D95551142FFDD6BA8AB77EF5AC8013DF65C028', TYP => 8 + 256 + 4096, KEY => UTL_I18N.STRING_TO_RAW(RPAD('mypassword', 32, '0'), 'AL32UTF8'), IV => UTL_I18N.STRING_TO_RAW('0000000000000000','AL32UTF8')), 'AL32UTF8') "復号" FROM DUAL;
復号 -------------------------------------------------------------------------------- 玉子焼(たまごやき)
OK! It’s Perfect!
CrypterObject で Security life!
どうですか、皆さん。この機能を使えば PowerBuilder でも簡単に暗号化 / 復号ができちゃうっしょ?
まずは、パスワードとか大事なデータだけでも暗号化してってアプリケーションにまさに御誂え向きの Security 機能になっていますよね。
・
・
・
今回、冒頭の挨拶で暗号化された文字を利用しました。
このブログを見たユーザーの皆様に「今回は誰のブログだろう?」と推理しながら読んでいただこうと、一生懸命ある方を演じながらブログを書きましたが。
引数やキーは今回のサンプルと同じものが利用できますので、冒頭の暗号化された文字列から PowerBuilder の復号機能を使用して是非担当を導き出してみてください!
明石市では、 ‘明石焼’ のことを ‘玉子焼(たまごやき)’ というそうです。たこ焼きも美味しいですが、明石焼も美味しいですよね。