目次
bcryptとは
bcryptとは、Blowfish暗号を基盤としたパスワードハッシュアルゴリズム(暗号学的ハッシュ関数)です。
一般的にパスワードは、元に戻すことが困難である「一方向性関数」の性質を持つハッシュ関数を用いてハッシュ値で保管します。
次の図は、パスワードを「平文」「暗号文」「ハッシュ値」で保管していた際のイメージ図です。
「平文」は漏洩したらパスワードが盗まれてしまいます。
「暗号文」は暗号化されていますが「暗号文」を復号する「鍵」があればパスワードを解読できます。パスワードが情報漏洩した時点で、もしかしたら「鍵」も漏洩しているかもしれません。そのため、パスワードを暗号文で保管するのは十分な対策とはいえません。
そして最後は「ハッシュ値」です。適切なハッシュ関数を使っていればハッシュ値へと変換した値を元に戻すことは非常に困難です。
スポンサーリンク
しかし「ハッシュ値」で保管するだけでは十分ではありません。
もし外部へパスワードの「ハッシュ値」が漏洩してしまった場合、「レインボーテーブル攻撃」や「総当り攻撃(ブルートフォース攻撃)」で「ハッシュ値」からパスワードを推測されてしまう危険性があります。
そのため、パスワードは「ソルト」と「ストレッチング」を実施した形でハッシュ値に変換します。
この「ソルト」や「ストレッチング」を考慮した形でハッシュ値へと変換してくれるのが、bcryptです。
ソルトとは
ソルトとは、パスワードをハッシュ値へと変換する際に、パスワードに付与するランダムな文字列のことです。
次の図はソルトのイメージ図です。パスワードにソルトを付与することで、ハッシュ値が全く異なる値で生成されます。
レインボーテーブル攻撃は事前に特殊なテーブルを用意し、その特殊なテーブルを使い不正入手したハッシュ値の元データを推測していきます。そのため、ソルトが付与されているハッシュ値だと推測できません。
ただし、そのソルトを使い新しいレインボーテーブルを生成することもできるため、ソルトは固定値ではなく、ユーザー毎にランダムな値で生成することが望ましいとされています。
ストレッチングとは
ストレッチングとは、ハッシュ関数を用いてハッシュ値への計算を数千回~数万回繰り返し行うことです。
弱いパスワードや文字数が長くないパスワードは、総当り攻撃(ブルートフォース攻撃)などで十分な時間をかければ元のデータを推測されてしまう可能性があります。(コンピュータの進化は早く、計算する処理速度も向上している。)
この時間を事実上不可能といえる時間にするためにストレッチングを実施します。
ストレッチングは回数が多いほど解析が困難になるも、サーバ負荷が増えるというデメリットもあるため、ストレッチングの回数は、サーバ負荷を考慮して検討する必要があります。
bcryptが生成するハッシュ値の構造
bcryptを利用すると次のようなハッシュ値が生成されます。このハッシュ値からハッシュアルゴリズム、ストレッチング回数、ソルトの値などが分かるようになっています。
$2y$10$1QVmWNzk.TsaZQLQ/zeI9OAZL02AWP.VdFPPyAc9hSc2Cp4yOXKtG
※上記のハッシュ値はあくまでも例です。
ハッシュアルゴリズム
先頭の「$2y$」の「2y」は、ハッシュアルゴリズムのバージョンを示します。bcryptには2, 2a, 2b, 2x, 2yなどのバージョンがあります。
ストレッチング回数(コストパラメータ)
次に「$10$」の「10」はストレッチング回数を示します。この数字は2のn乗のn部分を示しているので、今回は2の10乗で1024回ストレッチングされています。
ソルト(22文字)
ストレッチング回数の後の128ビット(22文字)はソルトを示します。上記例では「1QVmWNzk.TsaZQLQ/zeI9O」がソルトです。
結果のハッシュ値(31文字)
ソルトの後の184ビット(31文字)は結果のハッシュ値を示します。上記例では「AZL02AWP.VdFPPyAc9hSc2Cp4yOXKtG」が結果のハッシュ値です。