保存されたパスワードの上にソルトを使用するのが最善であるといつも聞いています。その後、なんらかの方法で連結されてハッシュされます。しかし、塩として使用するwhatはわかりません。良い塩は何でしょうか?
各ユーザーのパスワードを格納するテーブルがあるとします。
生成されているパスワードを「保存」するには、次の操作を行います
hashed_password = SHA(SHA(SHA(.... SHA( "1passworda12bc34de56fg")))))))))
そのhashed_passwordを、ログインとソルトとともにテーブルに格納します。
login password salt
--------------------------------------
john a7b82783... a12bc34de56fg
次に、ユーザーがアプリにアクセスしたことを確認するには:
hashed_password = SHA(SHA(SHA(.... SHA( "1passworda12bc34de56fg")))))))))
計算したhashed_passwordがデータベースに保存されているものと同じかどうかを確認します。パスワードが正しいかどうかがわかります。
それでおしまい!。あなたは好きなランダムソースから塩を手に入れることができます。なぜランダムなのでしょうか?ランダムではないソルトを使用すると、アプリをブルートフォースで攻撃することがはるかに容易になるからです。
パスワードハッシュ用のソルトの古典的な推奨事項は次のとおりです。
/dev/random
または/dev/urandom
現代のUnixの場合);たくさんの 関連トピックの過去の議論 があります。そして最も重要なのは、独自のパスワードハッシュ方式をしない実装する必要があります- 実証済みの十分にテストされた、ピアレビュー済みの実装を使用する必要があります( bcrypt/PBKDF2) 。
答えは「ほとんど何でも」ですが、他のものより強いものもあります。
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)を実行するのは簡単ですが、暗号的に安全ではありません(タイムスタンプとユーザー名は予測可能であるため、エントロピーが低いため)。しかし、ハッカーがデータベースを盗んだときでもとにかくソルトのコピーを持っているので、それは問題ではありません。
Saltにはランダムなビットを使用します。
Linuxでは/dev/random
を使用できます。環境ノイズに基づくカーネル乱数ジェネレータです。仮想マシンを除いて、それはかなり予測不可能です。つまり、ボックスに物理的なマウスが接続されているとしましょう。/dev/random
は、saltに適した高品質のランダムビットを提供します。
以下は、最初に良い 記事 です。外部参照も参照してください。
これが example Java code です。ソルトがどのように生成され、DBのcreateUser()
関数に格納されるかを確認してください。import Sun.misc. ...
の使用を除いて、非常に良いコード。