CakePHP2でパスワードハッシュのソルト付与、ストレッチング
はじめに
昨日触れましたが、先日パスワードをハッシュで保存する場合
- ソルトを付ける
- ストレッチングする
必要があることを教わりました。
その必要があることは知っていましたが具体的にどのように実装するのかやったことがなかったので試してみました。
対策する理由
- なぜソルトをつけるのか
パスワードを長くしてレインボーテーブルをつかった攻撃に対応するため
- なぜユーザごとに異なるソルトにするのか
同じパスワードでもユーザが違えば違うハッシュにしたいから
- なぜストレッチングするのか
総当たり攻撃に時間がかかるようにするため
試した環境
OS:CentOS6.5 64bit
Web:Apache 2.2 + PHP5.5
DB:PostgreSQL 9.3
CakePHPでよくあるUsersテーブルで認証する仕組みは構築済み
やり方
CakePHPでの認証処理はAuthComponentというコンポーネントが用意されていますが、こいつそのままではソルトは固定値でストレッチングしません。
これをユーザーごとにソルトを変更し、ストレッチングするようにしてみます。
PHP5.5で導入されたpassword_hash関数を使うPasswordHasherクラスを作成し使うようにします。
- /Controller/Component/Auth/SlowPasswordHasher.php
<?php App::uses('AbstractPasswordHasher', 'Controller/Component/Auth'); class SlowPasswordHasher extends AbstractPasswordHasher { public function hash($password) { //password_hashの戻り値にはcost(ストレッチ回数)とソルトを含むよ //costの13は2^13回のストレッチング //optionでsaltを与えなければ自動生成 return password_hash($password, PASSWORD_BCRYPT, ['cost' => 13]); } public function check($password, $hashedPassword) { return password_verify($password, $hashedPassword); } }
- /Controller/AppController.phpとかの$components
public $components = array( 'Auth' => array( 'authenticate' => array( 'Form' => array( 'passwordHasher' => 'Slow' ) ) ) );
- /Model/User.php
<?php App::uses('AppModel', 'Model'); App::uses('SlowPasswordHasher', 'Controller/Component/Auth'); class User extends AppModel { public function beforeSave($options = array()) { if (isset($this->data[$this->alias]['password'])) { $passwordHasher = new SlowPasswordHasher(); $this->data[$this->alias]['password'] = $passwordHasher->hash($this->data[$this->alias]['password']); } return true; } }
まとめ
PHP5.5のpassword_hash関数を使うと
簡単にパスワードハッシュのユーザごとに異なるソルト付与とストレッチングできました。
体系的に学ぶ 安全なWebアプリケーションの作り方 脆弱性が生まれる原理と対策の実践
- 作者: 徳丸浩
- 出版社/メーカー: ソフトバンククリエイティブ
- 発売日: 2011/03/03
- メディア: 大型本
- 購入: 119人 クリック: 4,283回
- この商品を含むブログ (136件) を見る