2011年9月24日土曜日

phpで暗号化

会員制システムを構築する場合、パスワードは暗号化して保存するのが標準的。
それは、例えばIDとPWの組み合わせが漏洩したとしても認証出来ないからだと思う。
でも暗号化方式が単純なものだったりすぐに復号できるような方式であれば、せっかく暗号化してもあんまり意味がないので方式の選択は重要だと思う。
基本的な関数は以下のとおり。
md5
crypt
sha1

で、md5とsha1についてはNG。
それはphpのマニュアルサイトにも書いてある通りです。

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

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

結局暗号化してしまっても、高速なコンピュータを使えばランダムにアクセスして復号化してしまえるので推奨しません、ということだと思います。



で、残ったcryptを使うわけですがその使い方も気を付けないと危険です。
それもcryptのマニュアルページに書いてありますが、標準DESベースで暗号化してしまうと、最初の8文字が同じ文字列は同じ文字列として解釈されてしまうようです。
例えばこんな。

<?php
$salt = "wow";
if(crypt("mypassworddesuyo", $salt) == crypt("mypassword", $salt)) {
echo "same";
} else {
echo "not same";
}
// output same
?>

マニュアルによる推奨アルゴリズムはBlowfishとなっているのでそれに適合するようなsaltを使用すればOKなのかなと思います。
例えばこんな。

<?php
$salt = "$2a$07$usesomesillystringforsalt$";
if(crypt("mypassworddesuyo", $salt) == crypt("mypassword", $salt)) {
echo "same";
} else {
echo "not same";
}
// output not same
?>

PEAR::Blowfishを使えば可逆暗号化方式を使うことが出来ます。
※確か、OpenPNE使ってた気がします。


おまけ
よく使われるハッシュ関数では不適切だというのなら、 パスワードをどうやってハッシュすればいいのですか?
パスワードをハッシュするときに検討すべき重要な二点は、 その計算量とソルトです。 ハッシュアルゴリズムの計算コストが増えれば増えるほど、 ブルートフォースによる出力の解析に時間を要するようになります。

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

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

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

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


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

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

0 件のコメント:

コメントを投稿