第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.
<?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_ , $portable_log2 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.
$ 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