多くの人が、レインボーテーブルが何をするのか、なぜこれが彼らを止めるのかを説明せずに「レインボーテーブルを止める」と言っています。
レインボーテーブルは、多数のハッシュを事前に計算し、それらを単純に必要とされるよりも少ないメモリに格納するための巧妙な方法であり、それらを使用してハッシュを非常にすばやく逆にすることができます。hash = md5(password)
およびなどのベア関数のテーブルhash = sha1(password)
は一般的です。
ただし、これらは、として記述できる任意のハッシュ関数に対して生成できますoutput = f(input)
。たとえば、すべてのユーザーパスワードにサイト全体のソルトを使用する場合hash = md5(salt+password)
、関数f
、を作成できますf(password) = md5(salt+password)
。したがって、この関数のレインボーテーブルを生成できます。これには長い時間がかかりますが、データベース内のすべてのパスワードを非常に迅速に解読できます。
パスワードごとにソルトが異なる場合、データベース内のすべてのパスワードを解読するレインボーテーブルを生成することはできません。すべてのユーザーに対して新しいものを生成することもできますが、それは無意味です-素朴なブルートフォースは遅くはありません。したがって、ユーザーごとに個別のソルトを用意することで、レインボーテーブルの攻撃を防ぐことができます。
これを実現するには、いくつかの方法があります。人気のある方法は次のとおりです。
- データベースに他の詳細と一緒に保存された、ユーザーごとの個別のソルト:
hash = hashfunction(salt + password)
- グローバルソルトとユーザーごとの固有の値:
hash = hashfunction(salt + password + user_id)
たとえば
- グローバルソルトとユーザーごとのソルト:
hash = hashfunction(global_salt + user_salt + password)
グローバルソルトを使用すると、データベースの外部(コードなど)に保存され、データベースが侵害された場合に攻撃者がアクセスできない可能性があるため、パスワードの解読が少し複雑になる可能性があります。暗号的にはそれほど多くはないと思いますが、実際には速度が低下する可能性があります。
最後に、実際の質問に答えるには:
ソルトをユーザーデータと一緒に保存しても、ハッシュが弱くなることはありません。ハッシュ関数は一方向です。無塩のパスワードであっても、パスワードのハッシュを考えると、そのパスワードを見つけるのは非常に困難です。ソルトの背後にある動機は、個々のハッシュをより安全にすることではなく、複数のハッシュのコレクションをより安全にすることです。無塩ハッシュのコレクションには、いくつかの攻撃ベクトルがあります。
- レインボーテーブル
123
一般的なパスワード( 、、 )をハッシュし、データベースにパスワードが存在するかどうかを確認してから、それらのアカウントを侵害しpassword
ますgod
- データベースで同一のハッシュを探します。これは、同一のパスワードを意味します(おそらく)