認証系の機能を持った gem を調べていた。見ていると多くの gem がパスワードのハッシュ化を BCrypt で実装している。きっと BCrypt ならば安心という一般的な合意があるのだろうとだけ推測して、あまり深入りはしなかった。
これだけであればただのつぶやきであるが、しばらく調べものを続けて、だんだん情報が溜まってきたので、実装には踏み込まない範囲でまとめてみる。ひとまず、 sorcery が実装しているモジュールにわかりやすい解説があったので紹介する。 wikipedia を合わせて読んでもいい。
sorcery/bcrypt.rb at v0.15.0 · Sorcery/sorcery · GitHub
bcrypt - Wikipedia
いわく、 SHA-512 アルゴリズムは十分安全なアルゴリズムであるが、 BCrypt はよりいっそう堅牢なアルゴリズムで、その根拠は計算量の大きさにあるという。効率が悪いアルゴリズムだと言い換えてもいい。つまり、大量の暗号化を行うときには当然パフォーマンスの問題が生じるが、それがとりもなおさずブルートフォース攻撃への耐性としても機能する、というところに特徴がある。
そんな BCrypt とどう付き合うべきか?
多くの gem がパスワードのハッシュ化を BCrypt で実装している、と書いた。実際、調べた限り sorcery 以外のすべての gem は BCrypt をハードコーディングしており、他のアルゴリズムは選べない。例えば人気の高い devise でも、アルゴリズムを変更するには devise-encryptable という別パッケージを導入しないといけない。それに sorcery も、複数の選択肢からアルゴリズムを選べるとはいえ、あくまでデフォルトは BCrypt である。
要するに、 SHA-512 でも十分安全とは言われても、あえて BCrypt を使わないのには勇気がいる。
まあ、パフォーマンスが悪いといっても、ウェブアプリケーションに導入するのであればそこまで極端なボトルネックにはならないと思う。それにパフォーマンスを懸念するのであれば、計算量 2N の変数 N はチューニング可能である。
便宜上 N と書いたが、このパラメータは cost と呼ばれる。以下の主だったライブラリでは cost は次のように設定されている。
gem | cost |
---|---|
bcrypt-ruby v3.1.13 | 12 [source] |
devise v4.7.1 | 11 [source] |
sorcery v0.15.0 | 10 [source] |
devise によると、テスト以外の環境では cost を 10 以上に設定することを推奨するそうなので、このラインは守りたいところ1。