PDEL for PHP5

Practical and Decryptable Encryption Library for PHP5   (Version 1.2.1)

Special thanks for your access. Sorry , this site is Japanese(UTF-8) version only.
   文字列等の「情報のDNA」に相当するものをハッシュ値と呼びます。(遺伝子の説明等で用いられるDNAです。)ハッシュ値の特徴は次のものです。

  • 暗号化の手法として良く用いられる。
  • 復号できない。
  • 暗号化の結果が固定長になる。
  • まれに衝突が発生する。
   特に最後の「まれに衝突が発生する」を補足するとexampleという7桁の文字列(文字コードはASCII)のSHA-1方式のハッシュ値は
c3499c2729730a7f807efb8676a92dcb6f8a3f8f
ですが、example以外の文字列(7桁とは限りません)であっても、上記と同じハッシュ値になることがある、ということです。

  • PDELでは、ハッシュ値を次の二つの目的で使用しています。
    • 復号の成功・失敗を判定するため。
      PDELは「暗号化する文字列のハッシュ値」を「暗号化結果の文字列」に埋め込んでいます。そして復号時、「復号された文字列のハッシュ値」と「暗号化時に埋め込まれたハッシュ値」を比較し、同じであれば復号成功、異なれば復号失敗としています。
    • セッション・ハイジャック・チェックを判定するため。
      PDELでのセッション・ハイジャック・チェックは「キー項目を連結した文字列のハッシュ値」を「暗号化結果の文字列」に埋め込んでいます。そして「復号時のキー項目を連結した文字列のハッシュ値」と「暗号化時に埋め込まれたキー項目のハッシュ値」を比較し、異なればセッション・ハイジャックされたとみなしています。
  • PDELのハッシュ値算出方式は、衝突の可能性の高い順に、CRC32、MD5、SHA-1の3種類から選択可能です。(いずれもPHP標準関数で提供されているものです。)
  • 厳密にはCRC32はチェックサムと呼ばれ、ハッシュ値と呼ぶことは情報工学的に不正確かも知れませんが、ハッシュ値の特徴を備えているので、PDELではハッシュ値として扱っています。(CRC32には更にいくつかの方式があり、PDELではcrc32bと呼ばれる方式を用いています。PHP関数のcrc32が、crc32b方式を採用しているからです。興味のある人はPHP関数のcrc32・hash_algos・hashで確認してください。)
  • PDELとは無関係ですが、ハッシュ値の話なので参考までに。パスワードをなんの工夫もせずMD5やSHA-1のみで暗号化しているシステムがありますが、あまり好ましいことではありません。パスワード以外の別の文字列(saltと呼ばれます)をパスワードと連結し、そのうえで暗号化したほうが好ましいです。saltも固定値ではなく、ユーザーごとに異なり、なおかつ絶対に変更されない情報(ユーザーID、入会日・初期登録日等)を基に生成した文字列で決定したほうが、より好ましいです。
   下図のようにロードバランサ(負荷分散装置)のあるWebシステムで、ユーザーのログインによりプロフィール情報が表示されると仮定します。(ログイン認証アクションをアクションA、プロフィール情報取得表示アクションをアクションBとします。参考までに「アクションAをPOSTメソッドで実行し、成功すればユーザーに操作させることなくリダイレクトにより、アクションBをGETメソッドで自動実行する」処理方式をPRGパターンと呼びます。)


  • アクションAで取得されたユーザーIDをアクションBでも使用するため、APサーバにユーザーIDを保存することがあります。「ユーザーIDを保存する特殊な変数」のことをセッション変数と呼びます。
  • セッション変数は通常、APサーバのファイルに保存されますが、変数のシリアライズ・アンシリアライズ等も含め、ファイルへのアクセスはPHP本体が行ってくれるので、プログラマはファイルであることを意識せずに使用できます。
  • APサーバのセッション変数とブラウザを紐付ける情報として、セッションIDと呼ばれる情報がAPサーバで採番されます。セッションIDは、通常はCookieとして、APサーバからブラウザに送信されます。(セッションID用のCookieは一時CookieやセッションCookieと呼ばれます。)Cookieが使用できない携帯では、URLにセッションIDが付与されます。

   上図のように、ロードバランサがアクションAを3号機に振り分けた場合、アクションBも必ず3号機に振り分ける機能のことをセッション・アフィニティ機能と呼びます。ロードバランサにセッション・アフィニティ機能が無ければ、セッション変数は基本的に使用できません。(セッション・アフィニティ機能があれば、上図のPCからアクションCやアクションD等が発生したとしても、必ず3号機に振り分けられます。)

  • セッション変数を使用せずに「アクションAで取得されたユーザーID」を「アクションBで使用する」には、ユーザーIDをブラウザに送信します。PRGパターンであればCookie、PRGではなくユーザーが明示的にアクションを送信するのであれば、Cookie以外に「HTMLの隠しタグ(inputタグのtype="hidden")、AjaxであればJavascriptの変数、Flash・Silverlight・HTML5のローカルストレージ等」が、セッション変数の役割を代替します。
  • ブラウザに送信する重要な情報は、改ざん・盗聴される可能性があるので、復号可能な暗号化が望まれます。
  • セッション・アフィニティ機能が無くても、SPF(Scratch Pad File。セッション変数を保存するファイル)を「APサーバ群で共有するファイルサーバ上に作成」または「SPFをAPサーバ群でレプリケーション」すれば、セッション変数は使用可能になります。もっともこの場合、SPFの物理ファイル名を「APサーバ群全体でユニークにする工夫」が求められます。
   以下の説明は、セッション・アフィニティ機能で記した事項の理解を前提にしています。もしサーバ側のセキュリティ対策が不十分であれば、次のようなリスクに直面します。

  • セッション変数を使用するシステムでは、正規ユーザー用に採番されたセッションIDが、悪意あるハッカーに盗まれると、正規ユーザーになりすまして様々な操作を行われる(セッション・ハイジャックされる)リスクがあります。


  • セッション変数を使用しないシステムであっても、正規ユーザー用のユーザーID等の重要情報が設定されたCookie等が、悪意あるハッカーに盗まれると、セッション・ハイジャックされるリスクがあります。
  • サーバ側アプリケーションにおけるセッション・ハイジャック対策の基本はログイン認証が成功した時点のユーザーの環境と、その後のユーザーの環境が同じであることを確認することです。ユーザーの環境とはIPアドレス・ブラウザの種類・ブラウザで使用する言語等です。(IPアドレスはモバイル系プロバイダを中心にインターネット接続後であっても変更されることがあるそうなので、注意してください。)
  • 上記以外の対策として「session_regenerate_id関数を使用する」「生成するHTMLのサニタイズ(PHPのhtmlspecialchars関数等で行う特殊文字変換。いわゆるクロスサイトスクリプティング対策)を徹底する」のは言うまでもありません。(セッション・ハイジャック以前のセキュリティ対策として「ログインの都度、ログインしたIPアドレスを登録メールアドレスに通知する」「ログインの都度、ワンタイムパスワードを登録メールアドレスに通知し、ワンタイムパスワードが一定時間内に入力された場合のみログインを認める」「ログイン用のIDやパスワード等が変更された場合、登録メールアドレスに、変更したIPアドレスと一緒にその旨を通知する」「ログインに一定回数連続して失敗するとアカウントをロックし、登録メールアドレスに、ログインしようとしたIPアドレスと一緒にその旨を通知する」「重複ログインを禁止する」等も必要に応じて検討すべきです。)
  • セッション・ハイジャック対策は、ユーザーへの啓蒙がより重要と思われます。具体的には、OSやブラウザ、Flash PlayerAcrobat Readerは支障が無ければ最新版を使用してもらう、ソフトウェアのインストール(ブラウザへのプラグイン追加も含む)は慎重に行ってもらう、ITに詳しくなさそうな人やサイトから紹介された短縮URLは確認してからアクセスしてもらう(短縮URL 確認をキーワードに検索すれば、短縮URLを確認できるサイトはたくさんヒットします)等です。