1

ログインフォームを持つローカルアプリケーションを構築しています。
データベースからユーザー名とパスワードを取得しています。

私にできることはたくさんあり、ある方法が別の方法よりも優れているかどうか疑問に思っているので、ここから先に進む最も安全な方法は何ですか.

SELECTテキストボックスから直接できます:

SELECT UserId, Password FROM Users_Table WHERE UserId = '" + userIdTextBox.Text + "' AND Password = '" + passwordTextBox.Text + "'".

SELECTそのテーブルからすべてを取得してから、テキストボックスと比較できますSqlDataReader

SELECT UserId, Password FROM Users_Table`<br>
While (myReader.Read())
{
   If (myReader["UserId"] == UserIdTextBox.Text && ...password)
   {
   }  
}

そして、それを行うには他にも多くの方法があります。続行するための最善/最も安全な方法は何ですか?

4

4 に答える 4

4

1.必要なものだけを返却してください(パフォーマンスパート1)

1人のユーザーのログインを検討しているためSELECT、他の情報を取得することは冗長です。キーワードを使用すると、句が満たされたSELECT TOP 1ときに1つのエントリのみを選択できます。WHERE

2.ストアドプロシージャ(パフォーマンスパート2)

オプションですが、ストアドプロシージャはSQLを最適化するのに最適です。基本的に、これらはコンパイルされたSQLであり、大量に実行されるSQLに最適であり、非常に複雑になる可能性があります。さらに、ストアドプロシージャはパラメータを使用するため、次のポイントに進みます。

3. SQLパラメータ(セキュリティパート1)

パラメータを使用しますSQLをパラメータ化することで、 SQLインジェクションを防ぐことができます。これは、見落とされたときに世界を傷つける可能性があります。使い方は簡単で簡単で、データベースと通信するときは絶対に必要です。

4.パスワードをソルトしてハッシュします(セキュリティパート2)

パスワードをプレーンテキストとして保存することは、私があなたがそうであることを意味しているのではなく、非常に危険です。最も強力なオプションは、パスワードをソルトしてからハッシュすることです。次に、ログインを試みるときに、ソルトとハッシュを適用します。これはあなたが比較するものです。

于 2012-07-27T14:35:18.563 に答える
4
  1. SQL コマンドとして連結テキストではなく、パラメーター化されたクエリを使用します。
  2. パスワードをハッシュし、ハッシュを保存しますを加えて味を調えます。
  3. ログイン試行時に、ユーザー入力のハッシュをハッシュ化されたパスワードと比較します。

基本的に、システム管理者を含む誰かにパスワード自体の値を知られる可能性はありません。このルールを念頭に置いて設計とコーディングを行い、車輪を再発明しないように努めれば、問題はありません。手動でパスワードを作成している場合は、最初のログオン時に「パスワードの変更が必要」オプションを有効にする必要があります ( Chris Shainさんに感謝します)。

于 2012-07-27T14:26:31.900 に答える
0

ここで行う最善の方法は、データベースにストアド プロシージャを設定することです。このようにして、クライアント側でパスワードを公開することもありません。

サーバーでストアド プロシージャを作成するには、次のようにします。

         CREATE PROCEDURE AuthenticateUser
(@username VarChar(25),
            @password VarChar(25)) AS
SELECT
COUNT(*)
FROM COMPANY
WHERE Login = @username
AND Password = @password
RETURN @@Rowcount

このストアド プロシージャにアクセスするコードは次のようになります。

        //Open a connection to the database using your connection string
        using (SqlConnection con = new SqlConnection("My Configuration string"))
        {
            //Open the connection
            con.Open();
            //Create a new command for the stored proc, using the existing connection just opened
            using(SqlCommand cmd = new SqlCommand("AuthenticateUser", con))
            {
            cmd.CommandType = CommandType.StoredProcedure;

                //Add the username and password to the command, as paramaters (Prevents a lot of security issues, such as SQL Injection)
            cmd.Parameters.Add("@username", SqlDbType.VarChar, 25).Value = UserIdTextBox.Text;
            cmd.Parameters.Add("@password", SqlDbType.VarChar, 25).Value = "Password";
                //A paramater for the return value, which will be a bool (Only 0 or 1 should be returned from the database/stored proc)
            SqlParameter ret = new SqlParameter("ret", SqlDbType.Int);
            ret.Direction = ParameterDirection.ReturnValue;
            cmd.Parameters.Add(ret);
                //Execute the query
            cmd.ExecuteNonQuery();
            if (Convert.ToBoolean(ret.Value) == true)
            {
                //Login Successful
            }
            else
            {
                //Login Failed
            }
        }
    }

SQLParamaters は、ユーザーが入力したものを盲目的に受け入れるのではなく、入力をサニタイズするため (データベース全体を削除する可能性があります)、ユーザーがデータベースとやり取りする量を減らすのに役立ちます。

しかし、覚えておいてください。また、パスワードをハッシュしてソルトする必要があります。これを見たい場合は、すでにスタックオーバーフローについての質問があります。そして、これをしないのは非常に悪い習慣です。

于 2012-07-27T14:47:46.540 に答える
0

人々は SQL インジェクションの脆弱性やハッシュ/ソルトについて言及しているので、ここでは取り上げません。

ただし、一般的な経験則では、可能な限りデータベースの近くでできるだけ多くの作業を行うことです。つまり、必要以上にデータベースからメモリにロードしないでください。

そのため、テーブル全体をメモリにロードする SQL データ リーダーなどは非効率的な選択となります。最良の選択は、ユーザー入力に一致するユーザー名/パスワード (ハッシュされたパスワード) の組み合わせを照会することです。次に、これらのレコードの count() が正確に 1 であることを確認します。1 未満の場合、ログインは失敗しています。1 より大きい場合、データベースに問題があります。ちょうど 1 の場合、ログインは成功しています。

于 2012-07-27T14:37:43.523 に答える