2011年10月4日

Yii Framework: ユーザのパスワード対策

Yii の Wiki にパスワードについての記事が上がっていたのでテストしてみました。

使われているのは phpass というパスワードハッシングフレームワークです (PHPフレームワーク関連なら CodeIgniter のライブラリ Tank_Auth にも採用されていますね) 。パスワードのセキュリティについて自分はあまり詳しくないので、以下に役に立ちそうなリンクを載せておきます。


上記のリンクを参考にしつつ、今回紹介されている Wiki の記事と照らし合わせて、ユーザ登録と、ログイン機能を実装していきます。

まず こちら から最新バージョンの phpass を DL、解凍して、protected/extensions 下に設置。続いて、protected/config/main.php に以下を追加。
(Yii の Wiki の記事とは異なり params の部分は array() を一つ省いています)
<?php
...
'import' => array(
...
'ext.PasswordHash',
),
...
'params' => array(
'iteration_count_log2' => 12,
'portable_hashes' => false,
),
...
view raw main.php hosted with ❤ by GitHub
iteration_count_log2 はストレッチング値です。例えば 8 の場合は 2^8 で 256 回繰り返す設定です。4~31 までの数値を設定できます。上記の場合は 12 なので 2^12 で 4096 回繰り返すことになります。数値が高ければ高いほどいいわけですが、その分、負荷がかかるので、環境、要件などに合わせて、慎重に設定すること。ちなみに今回の 4096 回くらいならユーザ登録、ログインともにほんの少しひっかかる程度の速度で 2147483648 回、つまり iteration_count_log2 が最大の 31 の場合は、待っても待っても全然進まない感じでした (もちろん環境によって違いがでます) 。

portable_hashes は true の場合、ハッシュ関数に md5 が使われ、false の場合、CRYPT_BLOWFISH, CRYPE_EXT_DESC, md5の順に試されます。

では、ログイン機能から作ってみます。
<?php
class UserIdentity extends CUserIdentity
{
private $id;
public function authenticate()
{
$model = User::model()->findByAttributes(array(
'username' => $this->username,
));
$ph = new PasswordHash(
Yii::app()->params['iteration_count_log2'],
Yii::app()->params['portable_hashes']
);
if (!$model) {
$this->errorCode = self::ERROR_USERNAME_INVALID;
} else if (!$ph->CheckPassword($this->password, $model->password)) {
$this->errorCode = self::ERROR_PASSWORD_INVALID;
} else {
$this->id = $model->id;
$this->errorCode = self::ERROR_NONE;
}
return !$this->errorCode;
}
public function getId()
{
return $this->id;
}
}
次にユーザ登録用のモデルサンプル。
<?php
class User extends CActiveRecord
{
public $password2;
...
public function rules()
{
return array(
...
array('password', 'compare', 'compareAttribute'=>'password2', 'message'=>'{attribute} とパスワード(確認)が一致しません。', 'on'=>'register'),
...
);
}
protected function beforeSave()
{
$ph = new PasswordHash(
Yii::app()->params['iteration_count_log2'],
Yii::app()->params['portable_hashes']
);
$this->password = $ph->HashPassword($this->password);
...
return parent::beforeSave();
}
}
view raw User.php hosted with ❤ by GitHub
あとは認証用モデル、コントローラ、ビューなどを作成していきます (ここでは省略) 。

0 件のコメント:

コメントを投稿