0

私は小さなGAEアプリケーション、Androidアプリのバックエンドを持っています。アプリに、データストアからデータを取得してユーザーに送信するサーブレットがあります。誰にもこのサーブレットを使用させたくないので、秘密鍵をアプリに保存し、リクエストごとにトークンを送信します-秘密鍵と現在のミリ秒のハッシュ文字列、およびミリ秒ハッシュで使用しました。サーバーはミリ秒と秘密鍵を取得し、それをトークンと比較しています。うまくいけば、サーバーはミリ秒をに保存しているHashSetので、それを二度と使用しないことがわかります。(誰かがデバイスデータを盗聴し、同じミリ秒とトークンを何度も送信する可能性があります)。

最初は、サーブレットクラスに静的フィールドを保持しましたが、このフィールドは永続化されておらず、インスタンスが破棄されるとすべてのデータが失われるため、後で間違いとして発見されました。

について読んだことがありますが、アプリのメモリが不足している場合やサーバーに障害が発生した場合でもMemcache、のデータが消去される可能性があるため、最適なソリューションではありません。Memcache

データストアを使用すると、リクエストが非常に遅くなるため、使用したくありません。

問題に直面しているのは私が最初ではないと思います。どうすれば解決できますか?

4

1 に答える 1

1

私は自分のアプリの1つで逆のアプローチを使用しました:

新しいクライアントが接続するたびに、サーバー上に3つのランダムな「チャレンジ」のセット(ミリ秒など)を生成します。これは、1分程度の有効期限でmemcacheに保存されます。次に、これらの課題をクライアントに送信します。クライアントが行うリクエストごとに、これら3つの課題のいずれかを使用する必要があります(秘密鍵でハッシュされます)。次に、サーバーは使用済みのチャレンジを削除し、新しいチャレンジを作成してクライアントに送信します。そうすれば、各チャレンジは使い捨てであり、リプレイアタックについて心配する必要はありません。

このアプローチに関するいくつかの注意事項:

  • 私が3つの課題を生成する理由は、複数のリクエストを並行して実行できるようにするためです。
  • チャレンジが長ければ長いほど、ランダムに再利用される可能性は低くなります(その場合、再生攻撃が可能になります)。
  • memcacheが保存したチャレンジを忘れると、アプリのリクエストは失敗します。失敗した場合の応答には、「他のすべての課題を忘れて、次の3つの新しい課題を使用する:...」コマンドが含まれます。
  • チャレンジをクライアントのIPアドレスまたは他の種類のセッション情報に関連付けて、誰かがあなたを「ハッキング」する可能性をさらに低くすることができます。
  • 一般に、クライアントに柔軟性を与えるよりも、サーバーに認証のチャレンジまたはソルトを生成させるのが常に最善です。

タイムスタンプの使用を継続したい場合に使用できるもう1つのアプローチは、最初の要求交換を使用して、サーバーインスタンスとクライアントデバイス間の時間オフセットを決定することです。次に、「現在の」タイムスタンプを持つリクエストのみを受け入れます。このためには、タイムオフセットを取得できる不確実性を判断し、それをタイムスタンプが最新でないようにするためのカットオフとして使用する必要があります。そのカットオフ期間内のリプレイアタックを防ぐために、使用された最後の2、3のタイムスタンプを保存して禁止する必要がある場合があります。これは、AppEngine、AFAIKが同じクライアントからのリクエストを優先的に同じインスタンスにルーティングするため、おそらくインスタンス内で実行できます。次に、インスタンスをシャットダウンして再起動する(つまり、許可されていないキャッシュをクリアする)のに、「現在の」カットオフよりも時間がかかる場合は、

于 2013-03-15T00:50:22.883 に答える