5

ハッシュ化されたパスワードとソルト値についてのアイデアがありました。私はハッシュと暗号化にかなり慣れていないので、これを投稿したいと思いました。ユーザーアカウントごとに一意のソルトを生成し、ソルトとハッシュ値をデータベースに保存する方が安全でしょうか? または、単一のソルト値を安全に保存しておき、パスワードをハッシュするたびにそれを再利用しますか?

たとえば、ユーザーは次のパスワードを使用します。

"secret"

私のコードは、次のソルト値を生成します。

"d1d0e3d4b3d1ed1598a4e77bb614750a2a175e"

次に、結果をハッシュして取得します。

"e8187dcbe8e2eabd4675f3a345fe21c98affb
 5544a9278461535cb67265b6fe09a11dbef572
 ce3a4a8f2275839927625cf0bc7bc46fc45d51
 12d7c0713bb4a3"

ハッシュされた結果とソルトは、アカウントが作成されたときに、ユーザー プロファイルのデータベースに保存されます。その後、ユーザーがログオンするたびに新しいソルトが生成され、パスワードとソルトが再ハッシュされてデータベースに保存されます。

何かご意見は?私が言ったように、これは私が持っていたアイデアの健全性チェックです。

4

4 に答える 4

7

私の意見では、ユーザーごとに固有のソルトを保存することをお勧めします。ユーザーがログインするたびにソルト/ハッシュの組み合わせを再生成することは、CPUサイクルを消費しない限り、少し無意味です。Rfc2898DeriveBytesクラスのようなものを使用して、安全なソルト/ハッシュコンボを生成することをお勧めします。

パスワードからハッシュを生成する簡単な例:

string password = GetPasswordFromInput();

using (var deriveBytes = new Rfc2898DeriveBytes(password, 32))  // 32-byte salt
{
    byte[] salt = deriveBytes.Salt;
    byte[] hash = deriveBytes.GetBytes(32);  // 32-byte hash
    SaveToDatabase(salt, hash);
}

そして、対応するパスワードのチェック:

string password = GetPasswordFromInput();
byte[] salt = GetSaltFromDatabase();
byte[] hash = GetHashFromDatabase();

using (var deriveBytes = new Rfc2898DeriveBytes(password, salt))
{
    if (deriveBytes.GetBytes(32).SequenceEqual(hash))
        Console.WriteLine("Password matches");
    else
        throw new Exception("Bad password");
}
于 2010-07-28T15:46:15.140 に答える
5

Adam が既に述べたように、ユーザーがログインするたびにパスワードをハッシュして保存することは、実際には何の役にも立ちません。

独自に作成するのではなく、実績のあるパスワード ハッシュ アルゴリズムの .NET 実装であるBCrypt.NETの使用を検討することをお勧めします。

使い方はとても簡単です:

// When setting password
string hashedPassword = BCrypt.HashPassword(password, BCrypt.GenerateSalt());

// Upon login
bool validPassword = BCrypt.CheckPassword(password, hashedPassword);

必要に応じて、パスワード ハッシュを計算する計算コストを変えることができます。たとえば、誰かが取得したデータベースに対して辞書攻撃を行うことをより困難にします。GenerateSaltこれは、メソッド呼び出しにパラメーターを追加することによって行われます。

BCrypt アルゴリズムの詳細については、こちらを参照してください

于 2010-07-28T15:25:16.020 に答える
3
  • 各ユーザーは、独自のソルトを持っている必要があります。
  • ユーザーがログインするたびにソルトを更新する意味はありません。これは、セキュリティに関して実際の目的には役立ちません。
  • ソルトはランダムに生成され、パスワードにリンクされていない必要があります。

ソルトの目的は、計算前の攻撃(レインボーテーブルなど)から保護することです。したがって、2人のユーザーが同じパスワードを持っている場合、それらは同じ最終ハッシュを持ちません。ソルトがシステム全体であり、ユーザーごとではない場合、これは当てはまらず、攻撃者はシステムのすべてのパスワードを1回だけ事前に計算する必要があります。各ユーザーが独自のソルトを持っている場合、事前計算攻撃を各ユーザーに対して個別に実行する必要があり、攻撃を実行不可能にします。

ソルトハッシュを使用しても、ブルートフォース辞書攻撃から保護することはできません。それらから保護するには、他の方法を使用する必要があります。

于 2010-07-28T15:49:12.527 に答える
1

ソルトの本当の目的は、事前計算攻撃を防ぐことです。なぜなら、ソルト自体は秘密であってはならないからです (つまり、外部からアクセスできるようにしても問題ありません)。したがって、ハッシュ (パスワード) と同じくらい簡単にハッシュ (ソルト + パスワード) できるため、ブルート フォーシングに対するセキュリティを提供することは意図されていません。

誰かが実際にパスワードのデータベースに対して 1 つのソルトの事前計算されたテーブルを作成し、そのテーブルを使用してデータベースで見つけたソルトされたパスワード ハッシュを検索すると思われる場合は、パスワードごとに一意のソルトを使用する必要があります。それ以外の場合は、心配しないでください。

于 2010-07-28T15:32:26.387 に答える