Nucleusプラグイン用DES暗号クラス
2006年12月2日
Nucleus プラグインでDES及び、トリプルDESを使うクラスを作成した。用途としては、ユーザとの情報のやり取りを行う際に、それを暗号化してセキュリティーの向上を図るなどがある。同様のセキュリティー確保の仕組みとして、Nucleus では ticket という概念があるが、それよりもう一段高いセキュリティーが期待される。利用方法は、ticket の実装よりほんの少し敷居が高い程度に分かりやすくさせたつもり。使い方を忘れないように、ここにメモしておく。
以下、これを利用したNP_Database ver 0.25のコードを引用しながら、説明。管理画面(database/index.php)で利用している。
1)正規の暗号を使っているかどうかのチェックと、コードの復号化
ここまでで、まず ticket が有効かどうかを判断する。この例では、POSTメソッドを使っているか、もしくは ?xxx=yyy などの記述があるかどうかを判断し、もしこれらのどちらかに該当すればチケットチェックするようになっている。
ここからが、今回作成したクラスの利用方法のメインの一つ。まず、2つのphp『des.php』と『desadmin.php』をこの順でインクルードする。次に、KAT_DES_PLUGIN_ADMINクラスのインスタンスを一つ作成する。このとき引数に、PLUGIN もしくは、PLUGINADMIN オブジェクトを指定する。なお、プラグインでは、『des_encryption』という名で、hidden option を一つ用意しておく。
続けて、KAT_DES_PLUGIN_ADMIN::getKeyFromTicket() 関数を、引数に ticket 値を与えて呼び出す。もし、この ticket を用いて暗号キーが作成されていたならば、その暗号キーが返される。もしキーが作成されていないならば、false が返される。実際にはこの暗号キーをプラグイン中で使うような設計にはなっていないので、この関数はここの例のように条件文として使うのが正しい。
次に、sid (セッションIDの意味のつもり;本当の意味でのセッションIDとは違うけれど…)が $_POST もしくは $_GET に指定されているかどうかを確認する。もし sid が指定されておらず、なおかつ別の値が $_POST もしくは $_GET に代入されている場合は不正なアクセスとみなしてプロセスを終了しなければならない。
sid が指定されている場合、KAT_DES_PLUGIN_ADMIN::resolveQueries() 関数を呼び出す。この関数内で、登録されている暗号キーを用いて sid の内容が復号化され、データが $_GET, $_POST などのスーパーグローバル変数に代入される。
この後は、$_GET, $_POST などの内容を読み出してそれぞれの作業を普通に行えばよい。
2)コードの暗号化
URL のLinkで情報を送信する場合は簡単で、次の例のように行う。
KAT_DES_PLUGIN_ADMIN::des_link() 関数を、引数に URL を与えて呼び出すだけである。この関数の戻り値には、sid (セッションID)と ticket (チケット)が含まれている。いずれも binhex 値なので、htmlspecialchars する必要は無い。
フォームを利用する場合は、少し複雑だ。ここでもやはり、sid と ticket の二つの値を hidden 値で指定してやる必要がある。
sid の方は、KAT_DES_PLUGIN_ADMIN::encrypt_binhex() 関数の戻り値を、ticket の方はKAT_DES_PLUGIN_ADMIN::ticket() の戻り値を利用する。
次に、encrypt_binhex() 関数の引数について説明する。
syntax:
param[¶m[¶m ....]]]
それぞれの param の構造には二種類ある
1)xxx=yyy
2)xxx (『=』が無い)
1)のケースは、あらかじめ決められている固定の hidden 値を指定する場合。
2)のケースは、フォームからの可変の情報を送信する場合に利用する。
ただし、xxx の部分が配列の場合は、必ず2)の方法を用いること。また、このケースでは、ルート名(『[』 『]』を含まない)のみしか現在のところは利用できない。
ノート
暗号は、国によってはその使用に制限のある場合がある(アメリカなど)。たしかDESの利用は大丈夫だったはずだし、ここで行っているような利用方法では問題が無いはずである。しかし、もし問題が生じた場合は、des.phpの内容を
とすれば良いはず。
以下、これを利用したNP_Database ver 0.25のコードを引用しながら、説明。管理画面(database/index.php)で利用している。
1)正規の暗号を使っているかどうかのチェックと、コードの復号化
$strRel = '../../../'; include($strRel . 'config.php'); include($DIR_LIBS . 'PLUGINADMIN.php'); $oPluginAdmin = new PluginAdmin('Database'); global $member, $manager, $CONF, $MYSQL_PREFIX; // Check if super-admin is logged in if (!($member->isLoggedIn() && $member->isAdmin())) { $oPluginAdmin->start(); echo '<p>' . _ERROR_DISALLOWED . '</p>'; $oPluginAdmin->end(); exit; } // Check the ticket first $queryexists=( strstr(serverVar('REQUEST_URI'),'?') || serverVar('QUERY_STRING') || strtoupper(serverVar('REQUEST_METHOD'))=='POST' ); if ( $queryexists && (!$manager->checkTicket()) ){ $oPluginAdmin->start(); echo '<p>' . _ERROR_BADTICKET . "</p>\n"; $oPluginAdmin->end(); exit; } $ticket=requestVar('ticket');
ここまでで、まず ticket が有効かどうかを判断する。この例では、POSTメソッドを使っているか、もしくは ?xxx=yyy などの記述があるかどうかを判断し、もしこれらのどちらかに該当すればチケットチェックするようになっている。
// Create an object of the 3xDES encryption class. // Check if there is the key that is designated to ticket include ('./des.php'); include ('./desadmin.php'); $oDesPluginAdmin = new KAT_DES_PLUGIN_ADMIN($oPluginAdmin);
ここからが、今回作成したクラスの利用方法のメインの一つ。まず、2つのphp『des.php』と『desadmin.php』をこの順でインクルードする。次に、KAT_DES_PLUGIN_ADMINクラスのインスタンスを一つ作成する。このとき引数に、PLUGIN もしくは、PLUGINADMIN オブジェクトを指定する。なお、プラグインでは、『des_encryption』という名で、hidden option を一つ用意しておく。
if ( $ticket &&(!$oDesPluginAdmin->getKeyFromTicket($ticket)) ) {// The key for decryption is set here. $oPluginAdmin->start(); echo "<p>There isn't the key for this ticket.</p>\n"; $oPluginAdmin->end(); exit; }
続けて、KAT_DES_PLUGIN_ADMIN::getKeyFromTicket() 関数を、引数に ticket 値を与えて呼び出す。もし、この ticket を用いて暗号キーが作成されていたならば、その暗号キーが返される。もしキーが作成されていないならば、false が返される。実際にはこの暗号キーをプラグイン中で使うような設計にはなっていないので、この関数はここの例のように条件文として使うのが正しい。
if (requestVar('sid')) $oDesPluginAdmin->resolveQueries(); // Resolve $_GET, $_POST, $SERVER['QUERY_STRING'], else if ($queryexists){ // and $_SERVER['REQUEST_URI'] from sid $oPluginAdmin->start(); echo '<p>' . _ERROR_DISALLOWED . "</p>\n"; $oPluginAdmin->end(); exit; }
次に、sid (セッションIDの意味のつもり;本当の意味でのセッションIDとは違うけれど…)が $_POST もしくは $_GET に指定されているかどうかを確認する。もし sid が指定されておらず、なおかつ別の値が $_POST もしくは $_GET に代入されている場合は不正なアクセスとみなしてプロセスを終了しなければならない。
sid が指定されている場合、KAT_DES_PLUGIN_ADMIN::resolveQueries() 関数を呼び出す。この関数内で、登録されている暗号キーを用いて sid の内容が復号化され、データが $_GET, $_POST などのスーパーグローバル変数に代入される。
この後は、$_GET, $_POST などの内容を読み出してそれぞれの作業を普通に行えばよい。
2)コードの暗号化
URL のLinkで情報を送信する場合は簡単で、次の例のように行う。
<a href="'.$oDesPluginAdmin->des_link($sslink.'i').'" title="'._NP_DATABASE_INSERT.'">
KAT_DES_PLUGIN_ADMIN::des_link() 関数を、引数に URL を与えて呼び出すだけである。この関数の戻り値には、sid (セッションID)と ticket (チケット)が含まれている。いずれも binhex 値なので、htmlspecialchars する必要は無い。
フォームを利用する場合は、少し複雑だ。ここでもやはり、sid と ticket の二つの値を hidden 値で指定してやる必要がある。
<input name="sid" type="hidden" value="'.$oDesPluginAdmin->encrypt_binhex($queries).'" /> <input name="ticket" type="hidden" value="'.$oDesPluginAdmin->ticket().'" />
sid の方は、KAT_DES_PLUGIN_ADMIN::encrypt_binhex() 関数の戻り値を、ticket の方はKAT_DES_PLUGIN_ADMIN::ticket() の戻り値を利用する。
次に、encrypt_binhex() 関数の引数について説明する。
syntax:
param[¶m[¶m ....]]]
それぞれの param の構造には二種類ある
1)xxx=yyy
2)xxx (『=』が無い)
1)のケースは、あらかじめ決められている固定の hidden 値を指定する場合。
2)のケースは、フォームからの可変の情報を送信する場合に利用する。
ただし、xxx の部分が配列の場合は、必ず2)の方法を用いること。また、このケースでは、ルート名(『[』 『]』を含まない)のみしか現在のところは利用できない。
ノート
暗号は、国によってはその使用に制限のある場合がある(アメリカなど)。たしかDESの利用は大丈夫だったはずだし、ここで行っているような利用方法では問題が無いはずである。しかし、もし問題が生じた場合は、des.phpの内容を
<?php if (!class_exists('KAT_DES_ENCRYPTION')){ class KAT_DES_ENCRYPTION { function des ($key, $message, $encrypt, $mode, $iv) { return $message; } } } ?>
とすれば良いはず。