2

クライアントがサーバーにリクエストを送信し、次に一意のリクエストIDを取得するアプリを作成しています。この一意の要求IDは、後でサーバーと再度対話するときにクライアントを認証するために使用されます。

クライアントの要求には、次の2つのタイプがあります。

  1. 新しいリクエスト。既存のIDがなく、サーバーからの応答によってIDが生成されて返されます。
  2. IDを持つ既存のリクエスト。次に、サーバーは、指定されたIDに対するクライアント要求を処理します。

私の問題は、IDをどのように生成するかです。JavaとMySQLサーバーデータベースを使用しています。自動インクリメントされたデータベース生成IDを使用すると、クライアントがIDを推測しやすくなります。別のクライアントは、それらを推測して誤用することにより、悪意を持っていくつかのIDを生成する可能性があります(IDを除いて、クライアント/サーバー間に認証はありません:<)

UUIDまたはその他のランダム化アルゴリズムを使用してランダムIDを生成する場合、データベース全体(数千のレコードが含まれる可能性があります)をチェックして、ランダムIDが実際に一意であるかどうかを実際にチェックして保証する必要がありますか?または、IDが存在し、パフォーマンスの問題が発生しないかどうかをデータベース内ですばやく確認できますか?

どのような対策をとるべきですか?一意のID以外に、クライアントとサーバー間の認証のために、より多くのセキュリティ対策を講じる必要がありますか?

4

6 に答える 6

2

セッションごとにエンコードされた一意のキーを作成します。このキーは、ユーザーの電子メールや現在の時刻など、そのユーザーの一意のデータを使用して作成されます。

String yourString = "user@email.com"+"timestamp"; 
byte[] bytesOfMessage = yourString.getBytes("UTF-8");
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] thedigest = md.digest(bytesOfMessage);

リクエストごとに一意のIDを生成し、有効期限のタイムスタンプ、ユーザーID、およびキーを含むデータベースのテーブルに保存します。リクエストごとに、「有効期限」がまだ有効な場合は更新し、有効期限が切れているか無効な場合はエラーを返します。

私が使用する有効なキーテーブルは次のようなものです。

userId(int)
key(varchar(32))
expiry(int)

次に、ユーザーが有効なセッションを開いているかどうかを確認したい場合は、そのテーブルでをチェックしuserId、それが一意の列であることを確認して、以前のセッションの履歴を保存しないようにします。

于 2012-05-21T11:25:53.747 に答える
2

JavaのUUIDを使用できます。何かのようなもの :

UUID uniqueKey = UUID.randomUUID();

また、それを使用したくない場合は、時間を使用できます。時間は常に変化するため、確実に使用したい場合は、乱数を追加してください。

于 2012-05-21T11:27:52.147 に答える
2

を使用java.util.UUID.randomUUID();すると、暗号的に安全なランダムUUIDを生成できます。

UUIDは128ビット長であるため、衝突の可能性はごくわずかですが、本当に衝突をチェックしたい場合は、アクティブなUUIDをデータベースに保存し、生成後に重複をチェックすることでそれを行うことができます。

于 2012-05-21T11:29:11.403 に答える
2

Spring Frameworkを使用している場合は、別のUUID実装が役立つ場合がありますorg.springframework.util.AlternativeJdkIdGenerator

IdGenerator generator = new AlternativeJdkIdGenerator();
UUID uuid = generator.generateId();

これはドキュメントからのものです:

毎回{@linkUUID#randomUUID()}を{@link org.springframework.utilとして呼び出す代わりに、最初のシードに{@link SecureRandom}を使用し、その後は*{@linkRandom}を使用する{@linkIdGenerator} .JdkIdGeneratorJdkIdGenerator}は行います。*これにより、安全にランダムなIDとパフォーマンスのバランスが改善されます。

于 2017-07-18T14:31:32.227 に答える
1

MySQL側で生成したい場合は、これで問題ないと思います

md5(concat(UNIX_TIMESTAMP(),<user_id>)) 

フィールドにインデックスが付けられている場合、クエリは長くはかかりません。

于 2012-05-21T11:30:19.110 に答える
0
  1. UUIDを使用して、ほぼ常に一意のベースIDを生成します。
  2. クライアントが推測やなりすましを困難にするために、ベースIDをハッシュします。
  3. 一意性制約のある列を使用して、ハッシュされたIDをデータベースに格納します。
  4. まれに、一意の制約に違反する場合は、上記の手順を繰り返します。
于 2012-05-21T14:44:56.390 に答える