web-dev-qa-db-ja.com

塩として何を使うべきですか?

保存されたパスワードの上にソルトを使用するのが最善であるといつも聞いています。その後、なんらかの方法で連結されてハッシュされます。しかし、塩として使用するwhatはわかりません。良い塩は何でしょうか?

43
Sal

各ユーザーのパスワードを格納するテーブルがあるとします。

生成されているパスワードを「保存」するには、次の操作を行います

  1. ユーザーからログインを取得する
  2. パスワードを取得する
  3. ランダムな値からソルトを生成します。/dev/randomから(@Michalが示唆したように) "a12bc34de56fg"を取得したとしましょう
  4. ハッシュ関数を使用して、ハッシュされたパスワードを生成します。元のパスワードが「1password」だったとします。SHAハッシュを使用します。次のようにします

hashed_pa​​ssword = SHA(SHA(SHA(.... SHA( "1passworda12bc34de56fg")))))))))

そのhashed_pa​​sswordを、ログインとソルトとともにテーブルに格納します。

login      password      salt
--------------------------------------
john       a7b82783...   a12bc34de56fg

次に、ユーザーがアプリにアクセスしたことを確認するには:

  1. ログインとパスワードを取得する
  2. そのログインのソルトをデータベースから取得します(ソルトはa12bc34de56fgになります)
  3. プレーンテキストのパスワードをソルトと連結し、すべてのハッシュを再度実行します。

hashed_pa​​ssword = SHA(SHA(SHA(.... SHA( "1passworda12bc34de56fg")))))))))

計算したhashed_pa​​sswordがデータベースに保存されているものと同じかどうかを確認します。パスワードが正しいかどうかがわかります。

それでおしまい!。あなたは好きなランダムソースから塩を手に入れることができます。なぜランダムなのでしょうか?ランダムではないソルトを使用すると、アプリをブルートフォースで攻撃することがはるかに容易になるからです。

13
woliveirajr

パスワードハッシュ用のソルトの古典的な推奨事項は次のとおりです。

  • A 128ビット以上のランダムな値 ;
  • 暗号的に健全な乱数発生器( /dev/randomまたは/dev/urandom 現代のUnixの場合);
  • 各エントリに固有(つまり、同じソルトを再利用せず、新しいパスワードごとに新しいソルトを生成します);
  • データベースにプレーンテキストで保存されます(ハッシュを検証するときにソルトを使用できるようにするため)。

たくさんの 関連トピックの過去の議論 があります。そして最も重要なのは、独自のパスワードハッシュ方式をしない実装する必要があります- 実証済みの十分にテストされた、ピアレビュー済みの実装を使用する必要があります( bcrypt/PBKDF2)

30
Jesper M

答えは「ほとんど何でも」ですが、他のものより強いものもあります。

Md5(salt.password)を使用しているとしましょう。

ソルトがないと、ハッカーはRainbowテーブルでハッシュを検索するだけで、ほとんどのパスワードをすばやくクラックします。

すべてのパスワードのソルトとして「x」を使用するとします。パスワードの多くはまだ見つかりますが、少なくなります。これは、パスワードが「p4ssw0rd」の場合、ソルトを使用すると「xp4ssw0rd」になり、少し難しくなりますが、それほど難しくはないためです。

ここで、すべてのパスワードの1つのソルトとして「%X88Fc + 7」を使用するとします。この時点では、レインボーテーブルは機能しません。しかし、すべてのパスワードに1つのソルトを使用した結果、ハッカーはその仮定を使用してRainbowテーブルを生成し、事前にRainbowテーブルを構築できます。はるかに安全ですが、完璧ではありません。

次に安全なオプションは、ユーザー名をソルトとして使用することです。つまり、「md5(username.password)」を使用します。繰り返しますが、これは標準のRainbowテーブルを無効にしますが、ハッカーは特定のユーザー名(「root」や「administrator」など)のRainbowテーブルを生成する可能性があるため、パスワードが変更されるたびに、ハッカーはRainbowを調べることができます再びそれをクラックする代わりにテーブル。

したがって、さらに安全にするために、ユーザーごとに異なるランダムソルトを選択します。これをユーザー名とパスワードのハッシュとともに保存する必要があります。これはRainbowテーブルを完全に打ち負かします。

単純なものではなく、「安全な」乱数ジェネレータを提案する人もいます。たとえば、ユーザーがアカウントを作成するときにMD5(timestamp + username)を実行するのは簡単ですが、暗号的に安全ではありません(タイムスタンプとユーザー名は予測可能であるため、エントロピーが低いため)。しかし、ハッカーがデータベースを盗んだときでもとにかくソルトのコピーを持っているので、それは問題ではありません。

10

Saltにはランダムなビットを使用します。

Linuxでは/dev/randomを使用できます。環境ノイズに基づくカーネル乱数ジェネレータです。仮想マシンを除いて、それはかなり予測不可能です。つまり、ボックスに物理的なマウスが接続されているとしましょう。/dev/randomは、saltに適した高品質のランダムビットを提供します。

以下は、最初に良い 記事 です。外部参照も参照してください。

これが example Java code です。ソルトがどのように生成され、DBのcreateUser()関数に格納されるかを確認してください。import Sun.misc. ...の使用を除いて、非常に良いコード。

1
Michał Šrajer