なぜPHPアプリにセキュリティホールが多いのか?
第40回 MOPS:安全性の高いパスワードハッシュ作成ツール - phpass
2010年11月4日
第32回 PHPセキュリティ月間
今回はパスワードを安全に保存するツールの紹介です。今まで数回に渡ってMOPSの成果の一部を紹介してきましたが,
- MOPS Submission 10: How to manage a PHP application’
s users and passwords - http://
www. php-security. org/ 2010/ 05/ 26/ mops-submission-10-how-to-manage-a-php-applications-users-and-passwords/ index. html
この論文は1位を取得した論文です。Drupal 7でこのライブラリが利用されていたので筆者はphassの存在を知っていました。phpassは本格的なパスワードハッシュツールで,
Alexander Peslyak氏が投稿した論文はライセンス条件が異なるので,
パスワード保存の問題
パスワードは言うまでもなく非常に高いセキュリティが要求される機密情報です。これはユーザ数が少ないサイトであっても同じです。多くのユーザは,
このため,
保存されたパスワードの強度は次のようになります。saltとstretchingについては後述します。
平文 | < | 平文のハッシュ | < | 平文+saltのハッシュ | < | 平文+stretching+saltのハッシュ |
Peslyak氏によると
パスワードは元のパスワードが解析できないような形で保存されるべきです。phpassはこれを実現するライブラリです。
平文
パスワードを平文で保存する問題点は指摘するまでもありません。SQLインジェクションなどでユーザデータが盗まれた場合,
平文のハッシュ
平文ままパスワードをデータベースに保存するのは危険なことは明らかなので,
ハッシュ化したパスワードは総当り攻撃で解析したり,
sha1/
平文+saltのハッシュ
saltとはパスワードハッシュを辞書攻撃から守るためのランダム文字列です。固定saltは簡単に利用でき,
平文+stretching+saltのハッシュ ─ パスワードの強化
ハッシュ関数は高速に動作するよう設計されています。この特徴はパスワードハッシュが盗まれた場合に解析されてしまうリスクを増加させてしまいます。パスワードを総当たり攻撃で解析しづらくする対策はkey/
ハッシュ関数の選択
Peslyak氏はどのハッシュ関数を使用するかは,
phpass ─ パスワードハッシングフレームワーク
phpassの解説の前に,
phpassは特に指定しない限り,
phpassはランダムにsalt文字列を生成し,
phpassの準備
phpassのホームページ
http://
からtar.
$ ls -F PasswordHash.php demo2/ demo3-4.diff demo5/ phpass-article.html demo1/ demo2-3.diff demo4/ demo5-6.diff test.php demo1-2.diff demo3/ demo4-5.diff demo6/
phpass-articleというディレクトリに中にあるPasswordHash.
phpassの使い方
phpassの使い方は非常に簡単です。test.
test.
<?php
require 'PasswordHash.php';
header('Content-type: text/plain');
$ok = 0;
# Try to use stronger but system-specific hashes, with a possible fallback to
# the weaker portable hashes.
$t_hasher = new PasswordHash(12, FALSE);
$correct = 'test12345';
$hash = $t_hasher->HashPassword($correct);
print 'Hash: ' . $hash . "\n";
$check = $t_hasher->CheckPassword($correct, $hash);
if ($check) $ok++;
print "Check correct: '" . $check . "' (should be '1')\n";
$wrong = 'test12346';
$check = $t_hasher->CheckPassword($wrong, $hash);
if (!$check) $ok++;
print "Check wrong: '" . $check . "' (should be '0' or '')\n";
(省略)
PasswordHashクラスのコンストラクタは以下のように定義されています。
function PasswordHash($iteration_
count_ log2, $portable_ hashes) - パスワードハッシュオブジェクトを初期化
$iteration_count_ log2:整数 ─ Stretching値
$portable_hashes:論理値
$iteration_
その他のメソッド
function HashPassword($password)
- 平文の$passwordをハッシュします。
$password:文字列 ─ 平文のパスワード
戻り値:ハッシュ化されたパスワード,エラーの場合 '*' が戻る function CheckPassword($password, $stored_
hash) - 平文の$passwordと既に保存済みの$stored_
hashとを比較します。
$password:文字列 ─ 平文のパスワード
$stored_hash:文字列 ─ DB等に保存されているハッシュ化されたパスワード
戻り値:論理値 - 1の場合同じ,0の場合異なる
test.
test.
$ php test.php Hash: $2a$08$/c4rG/rL7WRbtqCDqBGrp.B1tGJ97umGhoi2i9bVenw.bndbuZrSi Check correct: '1' (should be '1') Check wrong: '' (should be '0' or '') Hash: $P$BovV6HA5WqX5lICRGnLMd0E04GU8E.. Check correct: '1' (should be '1') Check wrong: '' (should be '0' or '') Hash: $P$9IQRaTwmfeRo7ud9Fh4E2PdI0S3r.L0 Check correct: '1' (should be '1') Check wrong: '' (should be '0' or '') All tests have PASSED
まとめ
Peslyak氏の論文には安全にデータベースへパスワードを保存するためにどのようにSQLインジェクションを防ぐか解説されていますが,
phpassは小さいライブラリですが強固なパスワードハッシュを簡単に生成してくれます。既存のプロジェクトに採用するためには,
phpassは優れたパスワードハッシュライブラリですが,
これまで数回に渡ってMOPS関連の記事を連載しましたが今回で最後です。3年前のMOPB
この記事に関連する書籍
-
Webアプリセキュリティ対策入門〜あなたのサイトは大丈夫?
本書は,Webサイトのセキュリティ確保のために必要な基礎知識と,安全なコードを書くために必要な基礎知識を解説しています。Webアプリケーションは比較的簡単に作成で...
-
はじめてのPHP言語プログラミング入門
Webアプリケーション構築ツールとしてPHPを取り上げた書籍は数多くありますが,言語の解説・入門書としての書籍はあまりありません。 本書は,プログラミング言語として...
バックナンバー
なぜPHPアプリにセキュリティホールが多いのか?
- 第46回 セキュリティ対策を考える上で欠かせないコンテクスト
- 第45回 入力バリデーションはセキュリティ対策
- 第44回 セキュリティ対策が確実に実施されない2つの理由
- 第43回 PHP 5.3のcrypt関数の問題
- 第42回 PostgreSQL 9.0に見るSQLインジェクション対策
- 第41回 PHP 5.3.4におけるセキュリティ上重要な仕様変更
- 第40回 MOPS:安全性の高いパスワードハッシュ作成ツール - phpass
- 第39回 MOPS:静的PHPソースコード脆弱性スキャナ RIPS
- 第38回 MOPS:PHPにおけるコード実行(2)
- 第37回 MOPS:PHPにおけるコード実行(1)