QA@IT

パスワードのソルトの要件は?

7298 PV

データベースにユーザーのパスワード情報を保存する場合、MD5やSHA-256でハッシュを取って、パスワードそのものではなくハッシュ値を保存することが多いと思うのですが、このとき安全性を高めるためにソルトを使うべきと言われていますよね。このソルトについて、ちょっと混乱しているので以下の点について教えて下さい。

  1. ソルトはDBとは別の場所に保存して隔離すべきか?
  2. ソルトは全ユーザーについて共通のもので良いのか?
  3. ソルトの長さは安全性に影響するのか?
  4. ソルトの文字列は乱数であるべきか?

回答

以下回答します。

Q1:ソルトはDBとは別の場所に保存して隔離すべきか?
A1:理論的には別の場所に置いた方がよいでしょうが通常は同じところに保存します
 ソルトをDBとは別の場所、例えばファイルに保存した方が安全性は高くなると考えられます。この場合、SQLインジェクション攻撃によりパスワードハッシュが漏洩しても、ソルトまでは漏洩しないのでハッシュ値から元パスワードを得ることは事実上不可能です。しかし、そこまでしない場合が多いと思います。
 その理由は、プログラミングが煩雑になり、トラブルの元になることが予想されるからです。DB以外にソルトを保存すると、トランザクションによる保護ができないので、ソルトデータが破損するリスクが高くなります。そうなると、最悪ケースでは全ユーザがログインできなくなります。これはセキュリティのCIAのうちA(可用性)が損なわれた状態です。
 しかも、ハッシュ値でパスワードを保存する理由は、仮にハッシュ値が漏れても元パスワードは保護されるというのが理由ですので、ソルトが判明しても安全性が損なわれるわけではありません。このため、データ破損のリスクや開発工数が増大するのに、敢えて別の場所にソルトを保存することはあまりしないようです。

Q2:ソルトは全ユーザーについて共通のもので良いのか?
A2:ユーザ毎に異なるものにすべきです
 ソルトが全ユーザで共通の場合、同じパスワードのユーザは全員同じパスワードハッシュ値が保存されることになります。そうすると、元パスワードが判明するリスクが高まります。
 攻撃例としては、漏洩したパスワードハッシュ値で同一のものの個数が多い順に並べ、辞書攻撃を仕掛けるという方法があります。利用の多いパスワードであれば、パスワード辞書に載っている可能性が高く、攻撃の効率が高くなります。
 このため、ソルトはユーザ毎に異なるものにすべきです。

Q3:ソルトの長さは安全性に影響するのか?
A3:最低限の長さが確保されれば、長さに影響しません
 ソルトの要件として、ある程度の長さ(20文字程度が目安)が必要です。これは、レインボーテーブルによる攻撃を避けるための要件です。しかし、これを満足していれば、長くしても安全性は高まりません。
 その理由は、通常ソルトはハッシュ値と共に保存するため、ハッシュ値が漏れる状況ではソルトも漏れているからです。ハッシュ値から元パスワードを得るには辞書攻撃あるいは総当たり攻撃を行いますが、ハッシュ値が分かっている前提では、ソルト長は攻撃難易度にあまり影響しません。ソルト長を長くするよりも、ハッシュ計算を繰り返し行うストレッチングの方が有効です。

Q4:ソルトの文字列は乱数であるべきか?
A4:乱数である必要はありません
 前述のように、ソルトの要件は、ある程度の長さがある(20文字程度以上)ことと、ユーザ毎に異なることです。これら条件が満たされれば、乱数である必要はありません。極端な話、20桁以上の一連番号でもよいのです。
 一般的に、乱数を用いるセキュリティ上の理由は、乱数の予測困難性です。しかし、ソルトの場合、ハッシュ値が漏れればソルトも漏れるので、予測困難性は意味がありません。
 しかし、現実の実装ではソルトとして乱数を用いることは多いです。それは、(ある程度の文字数のある)乱数も前述のソルトの要件を満たすからです。

編集 履歴 (0)
ウォッチ

この質問への回答やコメントをメールでお知らせします。