はじめまして、セキュリティに興味がある横山です。
今回は電子サービスのパスワードの保存にも使われいるハッシュ化とそれに用いるハッシュ関数についてご紹介いたします。
そもそもハッシュ化とは?
対象のデータに対してハッシュ関数と呼ばれる計算方法でハッシュ値と呼ばれる値を算出することをハッシュ化といいます。
ハッシュ関数の中でもパスワードのハッシュ化に用いられるものは、少しでも異なるデータを入力すると出力されるハッシュ値が大きく異なり、また、ハッシュ値から元のデータを復元することは困難な性質があります。
唐突な話ですが、パスワードを用いるログイン機能が実装されているWebサービスが攻撃されて、パスワードのデータが盗まれたと仮定してください。
このときパスワードがハッシュ化されていると、攻撃者が元のパスワードを復元するのは時間がかかり困難ですが、パスワードがそのままの状態で保存されていると攻撃者が見ただけで分かってしまいます。
パスワードがハッシュ化されていない状態で保存されているサーバに攻撃されて、ユーザが使っているパスワードがそのまま流出してしまった近年の事件としては、宅ふぁいる便の情報漏洩があります。
パスワードをハッシュ化するとメリットがあるのは上で話しましたが、ではパスワードをハッシュ化した場合、元のパスワードとどうやって照合すればいいでしょうか?
答えは、照合するパスワードも同じハッシュ関数でハッシュ化し、同じ値か比較します。
Webサービスでユーザを登録するときにパスワードをハッシュ化したとしましょう。
ユーザがログインしようとしたときに、入力されたパスワードをハッシュ化して登録時に保存したハッシュ値と比較します。
このようにして、元のパスワードと合っているかどうかの確認を行います。
つづいてパスワードを保存するのに用いられる最近のハッシュ関数を紹介いたします。
ハッシュ関数の種類
パスワードの保存に用いられる事が多い最近のハッシュ関数とは次のとおりです。
- Argon2
- Bcrypt
- PBKDF2
ハッシュ関数に使われるパラメータのチューニングが可能ならばArgon2、それが可能ではないならばBcrypt、Bcryptの実装がない、もしくは何かしらの理由があるならばPBKDF2にするのが良いとされています。
- Argon2
Argon2は比較的最近(2015/7)、パスワードハッシュのコンペで優勝したハッシュ関数になります。このハッシュ関数は、それぞれGPUと呼ばれる高速に並列計算が可能な機器からの攻撃と、ハッシュ値を算出中の機器を物理的に観測や計測することによる攻撃、どちらの攻撃にも防御力がある3つのバージョン(Argon2d、Argon2i、Argon2id)を提供します。
Argon2はハッシュ値の強度を調整するパラメータとして次の3つが指定できます。
- 使用メモリ量
- 反復回数(実行時間)
- 並行処理数
Argon2は使う機器に応じてこれらのパラメータをチューニングする必要があります。
参考までにスクリプト言語のひとつであるPHPはデフォルトの値として次の値をそれぞれ採用しています。
- memory_cost = 1024 KiB
- time_cost = 2
- threads = 2
出典:PHP RFC: Argon2 Password Hash Cost Factors
これらのパラメータを適切に選択できるならばArgon2が最良の選択と言えるでしょう。
- Bcrypt
Bcryptは暗号の1つであるBlowfishを基盤としたハッシュ関数です。Argon2ではパラメータを3つ指定できましたが、Bcryptではコストと呼ばれる強度を調整するパラメータがあり、コストが12の場合、反復回数は2の12乗になります。
- PBKDF2
PBKDF2は他のハッシュ関数とは毛色が違い、これはハッシュ関数を使って鍵と呼ばれるものを導出する関数になります。この関数は反復回数や出力されるキーの長さ、そして内部で使用されるハッシュ関数が強度を調整するパラメータになります。
この他に暗号学的ハッシュ関数であるSHA-512やMD5などがありますが、これらはそもそも単体では反復して計算するかどうかが規定されていない、ハッシュ値を出すときに用いられるソルト(計算するときにパスワードに追加されるランダムで一意の文字列です)を付与するかどうかも規定されていない、GPUによるアタックに弱い(効率的に計算されてしまう)などの問題があるため、上記であげた関数が使えないときに使用することを検討してください。
まとめ
- パスワードの保存方法にはハッシュ関数を用いたハッシュ化がある。
- ハッシュ関数の優先順位としては、詳しい人が居ればArgon2id、特に理由がなければBcrypt、その次にPBKDF2、使えるライブラリがとても少ない場合は暗号学的ハッシュ関数にソルトと計算の反復をする。
以上のことに気をつけて実装してください。