水無月ばけらのえび日記

bakera.jp > 水無月ばけらのえび日記 > 続・徳丸本のあれこれ ストレッチング処理の変更

続・徳丸本のあれこれ ストレッチング処理の変更

2011年6月28日(火曜日)

続・徳丸本のあれこれ ストレッチング処理の変更

更新: 2011年7月10日9時20分頃

徳丸本のあれこれを実践してみて気付いたことの続きです。

前回、ストレッチングの回数をどうするのかが難しいと書きました。負荷を心配しつつ1000回で実装してみたのですが、実際に動かしてみると処理が一瞬で終わってしまい、速すぎて心細く感じるほどでした。

アプリケーションの機能は一通り実装し終わり、テスト運用を始めたのですが、しばらく運用してみてもログインが遅いとか、それに伴って負荷が高くなるといったことは起きませんでした。

というわけで、もう少し遅くしてストレッチパワーをためた方が良いのではないかと考え、調整することにしました。

ハッシュアルゴリズムの変更

まず、ハッシュアルゴリズムをSHA512に変更しました。徳丸本 (www.amazon.co.jp)ではSHA256が使われていますが、SHA512の方が遅く、生成されるハッシュ値も長くなります。遅いのは普通はデメリットですが、今回はメリットになります。

※2011-07-10追記: 手元で実測した結果ではSHA512の方が少し遅かったので「遅い」と判断していましたが、春山さんからコメントをいただきました (twitter.com) (ありがとうございます)。64ビットCPUではSHA512の方が速いと言われているそうです。実装に依存する面もあるので、一概にどちらが遅いとは言えないようです。

ハッシュ値の長さは、16進表記で128文字。少し長い感じもしますが、varchar(255)のカラムにすんなり格納できますから問題ありません。

※データベースのサイズを節約したい場合は、Base64にしたり、バイナリで保存することにしても良いと思います。徳丸本のPHPのコードではhexdigestの形になっていて、それで特に問題なかったのでそのまま採用しました。

Rubyには標準でDigest::SHA512 (www.ruby-lang.org)がありますので、Digest::SHA512#hexdigestを呼ぶだけでOKです。ついでに、設定ファイルでDigestの種類を変更できるようにしておきました。

ストレッチ回数の調整

ハッシュアルゴリズムをSHA512に変更しても、速度はそれほど大きくは変わりませんでしたので、処理の回数も調整することにしました。

解析されにくくするためには、できるだけ遅くしたいところです。しかし、遅すぎるとログインのたびに利用者が待たされることになります。どのくらいを遅すぎると判断するのかは難しいところですが、今回は、0.1秒以内に処理できれば良いことにしました。

手元の環境でベンチマークを実行してみました。RubyにはBenchmark (www.ruby-lang.org)というクラスがありますので、rails consoleから以下のようなコードを実行しました。

Benchmark.measure { 1000.times{ User.password_digest('user_id', 'dummy_passphrase') } }

1回だけの測定では一瞬で終わってしまって誤差が大きいので、1000.timesで1000回実行するようにしています。ストレッチ回数の設定を変更しながら試していったところ、ストレッチ5000回が約0.07秒でした。処理速度は環境に依存すると思われますが、まあこのくらいで良いでしょう。

というわけで、ハッシュアルゴリズムをSHA512、ストレッチ回数を5000回に設定しました。本番反映してしばらく様子を見ましたが、特に問題も出ていないようです。もちろん、アルゴリズムや回数を変更すると既存のユーザーはログインできなくなりますので、パスワードの再設定は必要になりましたが。

なお、これはあくまで私が今回実装したシステムでの話です。今回開発しているアプリケーションはCMSで、ログインするのはサイト管理者、編集者、承認者だけ、その頻度も高くありません。そのため、ログイン処理の負荷が問題になることはあまり考えられないでしょう。一般の利用者がユーザー登録するようなシステムの場合、一度に多数のユーザーが頻繁にログインする可能性がありますので、もう少し慎重に検討する必要があるかもしれません。

関連する話題: セキュリティ / プログラミング / Ruby / 徳丸本 / Nightmare

最近の日記

関わった本など