PHPにおけるパスワードの扱いについて

Webアプリケーションでログインの機能をつける時、大抵ユーザーIDとパスワードを使う。アプリケーション内でのユーザーのなりすましを防ぐために、パスワードは丁重に扱わなくてはならない。

と、言うところまでは言葉では分かったが、実際どうすればいいのかがいまいち分からなかった。とりあえず、平文のままパスワードをデータベースの中に放り込むのは論外として、じゃあ暗号化だなということで調べ始めた。

すると、手軽な方法でPHPのネイティブな関数にcrypt()というものがあることが分かった。

PHP: crypt – Manual
http://www.php.net/manual/ja/function.crypt.php

第1引数で指定した文字列(パスワード)を第2引数で指定されたsalt(これで使用するハッシュ関数一緒に指定する)でハッシュした文字列を得るということでこれを「暗号化されたパスワード」としてデータベースに保存すればOKと言う事になる。

PHP: パスワードのハッシュ – Manual
http://www.php.net/manual/ja/faq.passwords.php

関連のこのページを読んで見るとハッシュアルゴリズムにはBlowfishが良いだろうというようなことが書いてあったので、それを使えばいいのかなとなんとなく理解した。つまるところ他のMD5やSHA1よりましであるようだ程度の認識だ。この関数で使用出来る用意されたアルゴリズムはBlowfish以上のものだとSHA256とSHA512で選択肢はそんなにない。利用できるかは設定によるようだが…とりあえず、あとは危険でないsaltの指定方法を探したのだがここでハマった。

結論としてはsaltについては十分に長くてそれなりに複雑であればなんでもいい。アカウントごとにsaltを用意してあげる必要がある。そしてsaltをハッシュとともに保存しておく。ということは分かった(時間がかかったが)。

問題はそれを調べる過程で本当にcrypt()を使っていいのかという疑問を持ってしまったことだ。

Webアプリでパスワード保護はどこまでやればいいか
http://www.slideshare.net/ockeghem/how-to-guard-your-password

セキュリティ関連で著名な方らしい、徳丸さんという方のスライドである。この中で「ストレッチング」と言うハッシュの計算を相当数繰り返す方法をとるべきであると主張されている。例のコードではhash()と言う関数でSHA256が使われ、それが1,000回繰り返されていた。

crypt()のSHA256の説明には「’rounds=<N>$’ で始まる場合は、数値 N がハッシュループの実行回数を表します。」と書いてあったのでこれがストレッチングに相当するのか?

http://www.akkadia.org/drepper/SHA-crypt.txt

このへん見るとそうっぽいんだけどそもそもこれ、UNIXの実装の話だし。…そうだとするとわざわざ自作する必要性がよくわからなくなる。

カテゴリー: プログラミング タグ: , パーマリンク

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください