身近なところからはじめるセキュリティ対策 | データの暗号化と復号

暗号化/復号

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 の復号機能を使用して是非担当を導き出してみてください!


明石市では、 ‘明石焼’ のことを ‘玉子焼(たまごやき)’ というそうです。たこ焼きも美味しいですが、明石焼も美味しいですよね。

テクニカルブログ 一覧を見る
PowerBuilder マイグレーション
PowerBuilder学習、動画で始めちゃう?