web-dev-qa-db-ja.com

ソルトハッシュ値はどこから取得する必要がありますか?

プレーンテキストで保存できないパスワードなどのハッシュ値にソルト値を追加する場合、ソルト値を取得するのに最適な場所はどこですか?コンテキストとして、これがWebページログインのパスワード用であると仮定します。

12

通常、列がありますcreated TIMESTAMPをユーザーテーブルに追加すると、ユーザーがいつ登録されたかを確認できます。 Saltに列を追加したくないので、タイムスタンプ列をsaltとして使用します。

SHA1(password + created)
7
Jonas

それは重要ですか?

塩には2つの目的があります。ハッシュ化されたパスワードの大規模なテーブル(「レインボーテーブル」)を使用することは非現実的であり、ハッシュのリストでは同一のパスワードが異なるように見えます。同一のパスワードの見た目を変えることで、複数の人が1つの特定のパスワードを使用するという問題を回避できます。

したがって、発生する可能性のある塩のグループが存在しないという意味で、各アカウントには独自の固有の塩があり、塩は過度に予測可能であってはなりません。 (多くのサイトが1から始まって数え上げられた場合、悪者は、例えば、低数の塩を含むRainbowテーブルを作成することができます。)それらは、一般的に予測できないこと以外の意味でランダムである必要はありません。それらはハッシュ自体よりも秘密ではないので、特に推測可能である必要はありません。

便利な方法を使用して、塩を生成します。アカウントの数と比較して多くの潜在的なソルト値(初期のUnixシステムは頻繁に2バイトを使用し、可能な数は65536)がある場合、セミランダム割り当てでソルトが重複することはほとんどありません。

7
David Thornley

新しいパスワード(登録、パスワードリセット、パスワード更新)を保存するたびに、1つの優れた手法は次のとおりです。

  • 新しいソルトを生成する
    • 暗号で保護された疑似乱数ジェネレータを使用する
    • 適切なサイズのソルトを使用してください-良い値は、基礎となるハッシュアルゴリズムのブロックサイズです(SHA-256の可能性があります)。
  • 新しいパスワードトークンを生成する
    • hmacキーとしてソルトを使用して、基になるハッシュアルゴリズム(SHA-256の可能性があります)からhmac関数を作成します
    • for i in (0...65536) { password = hmac(password) }
    • hmac関数の反復適用の結果はパスワードトークンです
  • saltとパスワードトークンを保存する
    • 元のパスワードを保存しない
    • 必要に応じて、基盤となるハッシュアルゴリズムと検出可能性のためのストレッチを保存します
3
yfeldblum

ソルトサーバー側を生成し、作成時にユーザーアカウントに割り当てます。フレームワークで使用可能な暗号生成APIを使用する方が良いですが、原則としてどのシーケンスでも使用できます。

通常、次のように保存されます。

User
-------------------
ID
Username
PasswordHashWithSalt

例:

PasswordHashWithSalt =

A15CD9652D4F4A3FB61A2A422AEAFDF0DEA4E703 j5d58k4b56s8744q

1
user8685

フレームワークを活用します。 .NETでは RNGCryptoServoiceProvider ...を使用できます。

        // If salt is not specified, generate it on the fly.
        if (saltBytes == null)
        {
            // Define min and max salt sizes.
            int minSaltSize = 4;
            int maxSaltSize = 8;

            // Generate a random number for the size of the salt.
            Random  random = new Random();
            int saltSize = random.Next(minSaltSize, maxSaltSize);

            // Allocate a byte array, which will hold the salt.
            saltBytes = new byte[saltSize];

            // Initialize a random number generator.
            RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();

            // Fill the salt with cryptographically strong byte values.
            rng.GetNonZeroBytes(saltBytes); 
        }

他のフレームワークには、活用できる同様のクラスが必要です。ランダム性を実現するために、ソフトウェアはしばしば上記のようにユーザーとRandomを採用します。 TrueCryptで採用されているオプションは、定義された領域内でマウスをランダムに動かしてソルトを提供することです。それは、具体的なニーズとセキュリティのレベルに要約されます。あなたの塩は単に!@#$%

1
Aaron McIver

Bcryptを使用して読み取り この記事 通常のハッシュだけでは、この時代では深刻な保護にはなりません。

SDRゼロナレッジパスワードプロトコル の使用を検討してください。これには多くのオープンソースライブラリがあり、特許がありません。

SDRはsaltを必要とし、それを取得するのに最適な場所はクライアントです。キーストローク、マウスの動き、環境変数、乱数、一時フォルダ内のファイル作成時間をハッシュして、予測できない方法でサーバーから離れてソルトを作成します。 SDRはソルト(大きな素数)であるユーザーパスワードを受け取り、検証キーを生成します。あなたはそれを彼らのマシンから決して出さないパスワードを保存しませんが、あなたが彼らがベリファイアキーとソルトに対応するパスワードを持っていることを確認できます。中間の男や辞書攻撃の影響を受けません。念のため、データベース列のキーとソルトを暗号化します。

1
simbo1905