web-dev-qa-db-ja.com

計算されたハッシュに基づいてクライアントを特定する

私は現在、iPhoneクライアントにデータを提供するWebアプリケーションを開発しています。データの所有者になるために、他のクライアントがデータを取得できないようにします。

サーバーとクライアント間で共有秘密鍵を使用できると思いました。ハードコードされた文字列で、タイムスタンプをソルトして、要求がクライアントの1つによって行われたことを確認します。したがって、リクエストは次のようになります。

http://domain.com/request/[desired_object_id]/[device_id]/[timestamp]/[hash]

私はアプリで次のようにハッシュを計算します:

hash = sha(desired_object_id + device_id + timetsamp + "mysecretkey")

サーバー側では、データを送信する前にハッシュが適切に生成されていることを確認します。 (「desired_object_id」で識別されるすべてのオブジェクトは、すべてのサブスクライバーが使用できます)。別の方法として、タイムスタンプではなくランダムキーを生成することもできます。

問題は、それが私には安全に聞こえないということです...データは重要ではありません、それは私が非加入者によって使用されるパブリックAPIを提供したくないということだけです。また、これを行うと、ユーザーが新しいクライアントバージョンに更新する必要があるため、秘密鍵を変更できなくなります(ビジネスにはあまり適していません...)

これに関する他の既知の問題はありますか?それを行うためのより良い方法はありますか?できれば同じ単純さで。

2
Julien

ここでの複数の問題:

  1. この設定では、クライアントに秘密鍵を強制的に配置します。まともなリバースエンジニアリングスキルを持っている人なら誰でもそれを取得でき、それから彼らはすべての要求を自由に再現します。
  2. これらすべての部分がクリアテキスト(URL)で表示されている場合、 'desired_object_idなどをハッシュに入れる意味はありません。これを行う唯一の理由は、攻撃者があなたの秘密鍵を見つけられないようにすることです。しかし、ここでのより簡単な防止方法は、単に良い(高エントロピー)秘密を選ぶことです。
  3. タイムスタンプは、ナンスの最も弱い形式です。サーバー側でタイムスタンプを再現する必要がある場合は、すべてのクライアントに適切に同期されたクロックを強制します。ナンスのためだけにそれを使用している場合、ナンスの重要な特性を認識できていません。それらはランダムでなければなりません。タイムスタンプはランダムではありません。時計がずさんな場合でも、可能なキースペースのごく一部を使用している可能性のある32ビット(42億秒)のうち、1日以内(1日あたり86400秒)になります。 、そしてそれはランダムな間隔でさえありません、それらはあなたがかなり知っている値(現在の時間)の周りにすべて一緒に集まっています。
5
Marcin

まず最初に:すべてのクライアントインスタンスに含まれているため、「ハードコードされた文字列」を秘密にすることはできません。 リバースエンジニアリング の簡単な餌食です。 =。攻撃者はすでにそれを持っています。有名な例は、PowerDVDなどの「承認済み」ソフトウェアプレーヤーに埋め込まれているDVDコンテンツの暗号化キーです...

したがって、探しているのはper clientsecret string-である必要があります。これは、パスワード、またはクライアントのCookieに格納されている値です。

次に簡単な答え:SSLを使用します(つまり [〜#〜] https [〜#〜] )。リクエスト内に、クライアントごとのシークレット文字列を埋め込みます(これはCookieで自動的に発生します)。残りはSSLが処理します。特に、SSLは、要求だけでなくデータ自体も盗聴者の詮索好きな目から保護します。シチューに含めるハッシュ関数とタイムスタンプの数に関係なく、自家製のスキームからはセキュリティの点で同等のものは得られません。

2
Thomas Pornin

私は stackoverflowに関する興味深い記事 を見つけました。これはこれを行うさまざまな方法を説明しています。

0
Julien