12

概要

Flash および/または JavaScript クライアントでのグローバルに一意な ID。現在のブラウザー/フラッシュで利用可能な RNG でこれを行うことはできますか?それとも、サーバー側のランダム性を備えた複合 ID を作成する必要がありますか?

詳細

オブジェクトのグローバルに一意の識別子を生成する必要があります。IDを交換できる必要があるJavaで書かれたサーバー側の「システム」が複数あります。これらの各システムには、新しいオブジェクトの ID を実際に生成する flex/javascript クライアントのセットもあります。無関係なシステムのセット全体でグローバルな一意性を保証する必要があります。たとえば、2 つの独立したシステムのデータベースをマージ/同期できる必要があります。これらの ID が競合しないこと、および一度作成されたオブジェクトの ID を変更する必要がないことを保証する必要があります。すべての ID についてサーバーに接続せずに、フラッシュおよび JavaScript クライアントで ID を生成できるようにする必要があります。サーバーが提供するシードまたはシステム ID に依存するソリューションは、サーバーが頻繁に接続されない限り問題ありません。完全に切断された状態で機能するソリューションが望ましいです。同様に、システムの事前登録を必要としないソリューションは、中央機関 (MAC アドレスの OUI など) に依存するソリューションよりも適しています。

明らかな解決策は、フラッシュの UIDUtil などの「UUID ジェネレーターを使用する」ことです。この関数は、特にグローバルな一意性を否認します。一般に、グローバルな一意性を保証するために PRNG に依存することには懸念があります。

提案されたソリューション

クライアントの安全な乱数ジェネレーターに完全に依存します。

Flash 11 以降にはflash.crypto.generateRandomBytesがあります。Javascript には window.crypto がありますが、これはかなり新しく、IE ではサポートされていません。マウスを使用してエントロピーを追加するsjclのようなソリューションがあります。

完全な RNG が与えられた場合、2 122のランダムな UID の衝突の可能性は隕石のように小さいことは理解していますが、JavaScript またはフラッシュ クライアントで実際にこの程度のランダム性が得られないのではないかと心配しています。さらに、暗号化 RNG の典型的な使用例が私のものとは異なることを懸念しています。セッション キーなどについては、攻撃者が予測できない限り、衝突は許容されます。私の場合、衝突はまったく受け入れられません。 一意の ID を確保するために、安全な RNG の未加工の出力に本当に依存する必要がありますか?

システム ID、セッション ID、およびオブジェクト ID を含む複合ID を生成します。

明らかな実装は、サーバーのインストール時にシステム UUID を作成し、クライアントごとのログイン セッション ID を (データベースなどに) 保持し、システム ID とセッション ID をクライアントに送信して、セッションごとのカウンターを保持することです。 . uid は、システム ID、セッション ID、クライアント カウンターの 3 つです。

これらを直接連結するか、暗号化ハッシュでハッシュすることを想像できます。特にハッシュへの入力が出力とほぼ同じサイズである場合、ハッシュ自体が潜在的に衝突を引き起こす可能性があることを懸念しています。しかし、ハッシュによってシステム ID とカウンターがわかりにくくなり、情報が漏洩する可能性があります。

インストール時にシステム ID を生成する代わりに、別の解決策として、DOI のように一意のシステム ID を配布する中央レジストリを用意することもできます。ただし、これにはさらに調整が必要ですが、グローバルな一意性を本当に保証する唯一の方法だと思います。

主な質問

  • ランダムまたは複合ベース?
  • システム ID を含めますか?
  • システム ID の場合: ランダムなシステム ID を生成するか、中央レジストリを使用しますか?
  • タイムスタンプまたはその他のノンスを含めますか?
  • ハッシュするかしないか?
4

4 に答える 4

4

最も簡単な答えは、クライアントごとにインクリメントされるサーバー割り当てのクライアント ID と、そのクライアントのフラグメントごとにインクリメントされる各クライアントの値を使用することです。クライアント ID とフラグメント ID のペアは、そのコンテンツのグローバルに一意の ID になります。

もう 1 つの簡単な方法は、サーバー上で一意の ID のセット (一度に 2k など) を生成し、それらをバッチで各クライアントに送信することです。クライアントが ID を使い果たすと、さらにサーバーに連絡します。

クライアント ID は、すべてのサーバーがアクセスできる中央リポジトリに格納する必要があります。

ピアツーピア環境内でフラグメントを一意に識別して特定するために使用される分散ハッシュの方法を調べるのに役立つ場合があります。一意性を主張するために介入できるサーバーがあることを考えると、これはやり過ぎかもしれません。

質問に答えるには、システム ID、ノンス、またはハッシュの複雑さが増すことによってもたらされる利点を判断する必要があります。

システム ID: システム ID は通常、ドメイン内のシステムを一意に識別するために使用されます。したがって、ユーザーが誰であるか、または開いているセッションの数は気にせず、デバイスが誰であるかだけを知りたい場合は、システム ID を使用します。これは通常、JavaScript や Flash などのユーザー中心の環境ではあまり役に立ちません。ユーザーやセッションが関連している可能性があります。

ナンス: ナンス/ソルト/ランダム シードは、ID を難読化またはスクランブルするために使用されます。これは、他の人が ID の元の値を推測できないようにする場合に重要です。これが必要な場合は、秘密暗号化キーで ID を暗号化し、ID を読み取る必要がある各コンシューマに公開復号化キーを渡す方がよい場合があります。

タイムスタンプ:クライアントのクロックの変動性を考慮すると (つまり、タイムスタンプが任意の時間またはタイムゾーンに準拠しているとは保証できません)、タイムスタンプはこのアプリケーションの疑似ランダム値として扱う必要があります。

ハッシュ:ハッシュは、一意のキーを作成するために (絶対に) 使用されることがよくありますが、その本当の目的は、大きな (場合によっては無限の) ドメインをより小さく、より管理しやすいドメインにマップすることです。たとえば、MD5 は通常、タイムスタンプ、乱数、および/または nonce データから一意の ID を生成するために使用されます。実際に起こっていることは、MD5 関数が無限範囲のデータを 2^128 の可能性のある空間にマッピングしていることです。これは大規模なスペースですが、無限ではないため、論理的には、2 つの異なるフラグメントに割り当てられた同じハッシュが (たとえ理論上だけであっても) 存在することがわかります。一方、完全ハッシュは各データに一意の識別子を割り当てようとしますが、最初から各クライアント フラグメントに一意の識別子を割り当てるだけであれば、これはまったく不要です。

于 2012-05-22T13:10:50.133 に答える
2

@pingの回答に基づいて中間点が構築されます。

  1. クライアント名、高解像度時間、およびオプションでその他の疑似乱数シードを使用します
  2. データをハッシュして UID を生成します (または、UUID の使用に直接進みます)。
  3. 結果をデータベースに入力するために中央サーバーに記録します
  4. 衝突は、特別なコードに値する状況としてではなく、目立つようにフラグが立てられたバグとして扱います。

UUID またはかなり長いハッシュでは、重複またはゼロの可能性があります。したがって、次のいずれかです。

A) アプリケーションの存続期間中、重複は発生しません。存続は良好です。B) 数十年にわたって重複、またはおそらく 2 つ (気紛れ!) が表示されます。これらのケースに対処するために手動で介入します。クライアントでサーバーを実行している場合は、余裕があります。C) 3 回目の衝突が発生した場合、コードに根本的な問題があり、これを調査して、繰り返しを回避するための措置を講じることができます。

このようにして、ID はクライアントで生成され、サーバーへの接続は一方向であり、操作上重要ではありません。シードはランダムである必要はありません。ハッシュによって ID の起源がわかりにくくなるため、構築された衝突が回避されます。衝突がなかったと確信できます。(その衝突検出コードをテストすれば!) このシナリオでは UUID で十分です。

ハッシュが衝突の可能性を高める唯一の方法は、元のシード情報の内容がハッシュのサイズに近づく場合です。それは非常にありそうもないことですが、そうであり、まだ微小隕石について考えているのであれば、ハッシュ値のサイズを増やしてください.

于 2014-08-07T20:57:00.757 に答える
2

迅速で汚いもので、ユースケースではうまくいかないものもあります -

Java の UUID を使用し、それを clientName のようなものと結合します。これでmultiple client and multiple server問題は解決するはずです。

この背後にある理論的根拠は、同じナノ秒で 2 つの呼び出しを取得する可能性が低いということです。以下のリンクを参照してください。ここで、clientName を UUID と結合することで、クライアント間で一意の ID を確保し、同じナノ秒内に同じクライアントが 2 回呼び出すユース ケースのみを処理する必要があります。

ID を生成する Java モジュールを作成し、Flash にこのモジュールと通信させることができます。
ご参考までに、UUID を使用した一意の ID 生成は本当に一意ですか? を参照してください。
Java と Flash を相互に通信させる

于 2012-05-28T12:52:07.230 に答える
1

私の2セント..各サーバーはDBテーブルをロックし、そこからIDを取得してインクリメントします。これはサーバーの一意の ID になります。

接続している各クライアントは、サーバーによって発行された一意の識別子と組み合わせて、この ID を取得します。この一意のキーは、このサーバーに対して一意である必要がありますが、別のサーバーが同じ ID を別のクライアントに発行する可能性があります。

最後に、各クライアントは各リクエストに対して一意の ID を生成します。

3 つすべてを組み合わせると、システム全体で真に一意のグローバル ID が保証されます。最終的な ID は次のようになります。

[server id][client id][request id]
于 2013-12-25T15:34:11.570 に答える