downloads | documentation | faq | getting help | mailing lists | licenses | wiki | reporting bugs | php.net sites | links | conferences | my php.net

search for in the

PHP と HTML> <PHP の使いかた
[edit] Last updated: Fri, 25 May 2012

view this page in

安全なパスワードハッシュ

この節では、なぜハッシュ関数を使ってパスワードを守るのかについての理由と、 ハッシュ処理を効率的に行う方法について説明します。

なぜ、アプリケーションのユーザーが登録したパスワードをハッシュしなければならないのですか?

パスワードのハッシュは、最も基本的なセキュリティ要件のひとつです。 ユーザーからパスワードを受け取るアプリケーションを設計するときには必ず考慮しなければなりません。 ハッシュしなければ、パスワードを格納したデータベースが攻撃を受けたときにパスワードを盗まれてしまいます。 それは即時にアプリケーションが乗っ取られることにつながるし、 もしそのユーザーが他のサービスでも同じアカウント・同じパスワードを使っていればさらに被害が大きくなります。

ユーザーのパスワードにハッシュアルゴリズムを適用してからデータベースに格納しておくと、 攻撃者が元のパスワードを知ることが難しくなります。 とはいえ、パスワードのハッシュ結果との比較は可能です。

しかし、ここで注意すべき点は、パスワードのハッシュ処理はあくまでもデータベースへの不正アクセスからの保護にすぎず、 アプリケーション自体に不正なコードを注入される攻撃からは守れないということです。

よく使われるハッシュ関数である md5()sha1() は、なぜパスワードのハッシュに適していないのですか?

MD5 や SHA1 そして SHA256 といったハッシュアルゴリズムは、 高速かつ効率的なハッシュ処理のために設計されたものです。 最近のテクノロジーやハードウェア性能をもってすれば、 これらのアルゴリズムの出力をブルートフォースで(力ずくで)調べて元の入力を得るのはたやすいことです。

最近のコンピュータではハッシュアルゴリズムを高速に「逆算」できるので、 セキュリティ技術者の多くはこれらの関数をパスワードのハッシュに使わないよう強く推奨しています。

よく使われるハッシュ関数では不適切だというのなら、 パスワードをどうやってハッシュすればいいのですか?

パスワードをハッシュするときに検討すべき重要な二点は、 その計算量とソルトです。 ハッシュアルゴリズムの計算コストが増えれば増えるほど、 ブルートフォースによる出力の解析に時間を要するようになります。

PHP には、 使うアルゴリズムを指定してハッシュを実行できる関数がふたつ組み込まれています。

まず最初のハッシュ関数は crypt() で、これはネイティブで数種のハッシュアルゴリズムに対応しています。 この関数を使うときには、選択したアルゴリズムが使用可能なことが保証されています。 PHP には各アルゴリズムのネイティブ実装が含まれているので、 仮にシステムがサポートしていない場合でもそのアルゴリズムを使えるのです。

もうひとつのハッシュ関数は hash() で、 これは crypt() よりもさらに多数のアルゴリズムやその亜種に対応しています。 しかし、crypt() が対応しているアルゴリズムのいくつかには未対応です。 Hash 拡張モジュールは PHP に同梱されていますが、コンパイル時に無効化することもできます。 したがって、常に使えるとは限りません。一方 crypt() は PHP のコアに含まれているので、いつでも使えます。

パスワードのハッシュ用として推奨するアルゴリズムは Blowfish です。 これは MD5 や SHA1 に比べて圧倒的に計算量が多く、それでいてスケーラブルだからです。

ソルトとは?

暗号理論におけるソルトとは、ハッシュ処理の際に追加するデータのことです。 事前に計算済みのハッシュとその元入力の対応表 (レインボーテーブル) で出力を解析される可能性を減らすために利用します。

端的に言うと、ソルトとはちょっとした追加データです。 これをつけるだけで、ハッシュをクラックするのが劇的に難しくなります。 事前に計算済みのハッシュとその元入力を大量にまとめた表が、オンラインで多数公開されています。 ソルトを使えば、そのハッシュ値がこれらの表に含まれている可能性を大きく減らすことができます。



add a note add a note User Contributed Notes パスワードのハッシュ
alice2287 at live dot com 13-Mar-2012 04:25
For those wishing to increase the computational cost of brute-forcing their password hashes by iterating the hash command multiple times, but don't want to increase the risk of a hash collision, simply re-append the password to the hash each iteration.

<?php

$iterations
= 10;
$hash = crypt($password,$salt);
for (
$i = 0; $i < $iterations; ++$i)
{
   
$hash = crypt($hash . $password,$salt);
}

?>

This, of course, can be used with md5(), sha1(), etc. as well as crypt().

Some other recommendations:

- Use the highest number of iterations possible without introducing a significantly noticeable delay to authenticating users, or causing more CPU use than your host will allow.
- Use a unique salt for each user, ideally a random one.
- Use a salt of at least 24 bytes, especially if you're using a weaker algorithm like MD5 or SHA-1.

 
show source | credits | sitemap | contact | advertising | mirror sites