PR

多くのWebアプリケーション作成やシステム開発には、ユーザー情報の管理が付いて回ります。ユーザーのパスワードはデータベースやテキストに保存されることになりますが、このパスワードの扱いは極めて慎重に行う必要があります。

結論から申し上げますと、

パスワードを保存する際には絶対に不可逆暗号をかけなければなりません。

では、なぜパスワードは不可逆暗号化して保存しなければならないのでしょうか。

理由1.運用者がパスワードを知りえる

システムの運用に際し、パスワード格納場所にアクセス出来る権限を持つ人が一人とは限りませんし、運用会社が移る事なども考えられます。もし生のパスワードリストを取得できる立場にいる運用者の中に悪意を持った人物が混ざってしまったとしたら、その人はそのリストをいくらでも悪用できますし、最悪、ブルートフォース攻撃のような力技ツールに流し込む為のパスワードリストに追加されることになるでしょう。

理由2.万が一、情報が漏洩した場合

万が一にも生パスワードが付随した個人情報が漏洩するということになると、目も当てられません。利用者は別システムで同じパスワードを使う事があるので被害が計り知れません。生のパスワードの桁数がわかるだけでも非常に問題で、パスワードが数値4桁だった場合、銀行の暗証番号にも使用している可能性を想像したりするのではないでしょうか。

上記2点がパスワードを暗号化しなければならない主な理由となります。稼動システムのパスワードの漏洩だけではなく、パスワードリストの2次利用の危険を未然に防止しなくてはなりません。可逆暗号ではなく、不可逆暗号にしなくてはならない理由はやはり運用者が複合化のキーを知りえるからです。パスワード取り扱いの基本姿勢として、本人以外がパスワードを知りえない設計にする事が大切です。また、パスワードを暗号化するとシステム設計する際に制限が出てきます。例えばパスワードリマインダーなどの機能をつける事は出来ず、パスワードを忘れた場合の措置を考えなくてはなりませんし、認証方法メカニズムも変わります。

○認証スクリプト例
    
  $user_id  = $db->quoteSmart($_POST['user_id']);
  $password = $db->quoteSmart(sha1($_POST['password']));

  // DBの暗号化されたものと、入力値を同様に暗号化したものを比較する
  $result = $db->queryOne
("SELECT user_id FROM member_m WHERE user_id = {$user_id} AND password = {$password}");

  if ($result) {
    // 認証成功
    return true;
  } else {
    // 認証失敗
    return false;
  }

セキュリティホールの多いと言われがちなPHPアプリケーション。設計をしっかり提案・実装してこのような意識を払拭しましょう。



(アシアル 海原才人)


この記事は、アシアルが運営するPHP開発者のためのポータル&コミュニティサイト「PHPプロ!」で毎週配信しているPHP・TIPSメーリングリストを再録したものです。
同サイトでは、他にもPHP最新ニュースや、困ったときのQ&A掲示板、初心者向けのPHP講座など、PHP開発者をサポートする情報を掲載しています。