3

前の開発者が書いたシステムを引き継いでいます。システムは管理者にユーザー アカウントを承認させます。管理者が承認すると、システムは次の方法を使用してパスワードをハッシュし、データベースに保存します。ハッシュされていないパスワードをユーザーに送信します。ユーザーがログインすると、システムはまったく同じ方法を使用して、ユーザーが入力した内容をハッシュし、データベースの値と比較します。データベース エントリがユーザーのエントリと一致しない場合が数回あります。そのため、メソッドが常に同じ値をハッシュしているとは限らないようです。このハッシュ方法が信頼できないかどうか、また信頼できるようにする方法を知っている人はいますか? ありがとう。

    private string HashPassword(string password)
    {
        string hashedPassword = string.Empty;

        // Convert plain text into a byte array.
        byte[] plainTextBytes = Encoding.UTF8.GetBytes(password);

        // Allocate array, which will hold plain text and salt.
        byte[] plainTextWithSaltBytes =
                new byte[plainTextBytes.Length + SALT.Length];

        // Copy plain text bytes into resulting array.
        for(int i = 0; i < plainTextBytes.Length; i++)
            plainTextWithSaltBytes[i] = plainTextBytes[i];

        // Append salt bytes to the resulting array.
        for(int i = 0; i < SALT.Length; i++)
            plainTextWithSaltBytes[plainTextBytes.Length + i] = SALT[i];

        // Because we support multiple hashing algorithms, we must define
        // hash object as a common (abstract) base class. We will specify the
        // actual hashing algorithm class later during object creation.
        HashAlgorithm hash = new SHA256Managed();

        // Compute hash value of our plain text with appended salt.
        byte[] hashBytes = hash.ComputeHash(plainTextWithSaltBytes);

        // Create array which will hold hash and original salt bytes.
        byte[] hashWithSaltBytes = new byte[hashBytes.Length +
                                            SALT.Length];
        // Copy hash bytes into resulting array.
        for(int i = 0; i < hashBytes.Length; i++)
            hashWithSaltBytes[i] = hashBytes[i];

        // Append salt bytes to the result.
        for(int i = 0; i < SALT.Length; i++)
            hashWithSaltBytes[hashBytes.Length + i] = SALT[i];

        // Convert result into a base64-encoded string.
        hashedPassword = Convert.ToBase64String(hashWithSaltBytes);

        return hashedPassword;
    }
4

2 に答える 2

4

この関数は、salt でハッシュを行います。これは、同じパスワードに対して異なるハッシュを生成し、テーブルの検索をより困難にするテクニックです。

ハッシュは、同じソルト値を持っている場合にのみ同じです。

この手法の詳細については、ウィキペディアhttp://en.wikipedia.org/wiki/Salt_%28cryptography%29を参照してください。

http://msdn.microsoft.com/en-us/magazine/cc164107.aspxを引用:

攻撃を遅くするには、塩を使用します。ソルトは、パスワードをハッシュ化する前に味付けする方法であり、攻撃者が事前に計算した辞書を役に立たなくします。これがその方法です。データベースにエントリを追加するときはいつでも、salt として使用される数字のランダムな文字列を計算します。Alice のパスワードのハッシュを計算するには、Alice のアカウントのソルト値を検索し、それをパスワードの先頭に追加して、それらを一緒にハッシュします。結果のデータベースは次のようになります。

<users>
  <user name='Alice' salt='Tu72*&' password='6DB80AE7...'/>
  <user name='Bob'   salt='N5sb#X' password='096B1085...'/>
  <user name='Fred'  salt='q-V3bi' password='9118812E...'/>
</users>

現在、Bob と Fred が同じパスワードを使用していることを確認する方法がないことに注意してください。塩自体は秘密ではないことに注意してください。

于 2010-05-17T04:52:29.237 に答える
1

手順がランダムな意思決定を使用せず (つまり、完全に決定論的である)、使用されるアルゴリズムの実装が同じである場合 (そして、そうであるべきです - SHA256 はどこでもまったく同じように動作するはずであり、同じことが起こります) Base64 文字列の場合)、アルゴリズム自体が「値を同じようにハッシュしていない」可能性はほとんどありません。

エラーを再現できない場合 (つまり、サーバーでハッシュされたときに常に 1 つのハッシュを生成し、クライアントによってハッシュされたときに別のハッシュを生成する値を見つける)、値が正しく送信および受信されていることを確認する必要があります。クライアントがハッシュ化されていないパスワードをスクランブルしてしまったのではないでしょうか? サーバーがクライアントから破損したデータを受信して​​いる可能性がありますか? サーバーデータベース自体のデータが何らかの形で変更された可能性がありますか? すべてのトランザクションが検証されていることを確認してください。つまり、ユーザーが破損したパスワードを受信できないようにしてください。

于 2010-03-19T15:09:00.013 に答える