web-dev-qa-db-ja.com

APIキーメカニズムを実装する方法

まず、質問のタイトルがよくわからないので、もっと良いアイデアがあれば、遠慮なく教えてください(:

APIを提供するサービス(Twitterやcoなど)が開発者としてAPIキーを使用して第三者がそのキーを取得できないようにするベストプラクティスの例について教えてください。

私は悪い例で私の考えを説明します:

私の知る限り、TwitterとFBではAPIリクエストにAPIキーを使用する必要があります。これはサーバー側アプリケーションでは問題ありませんが、Webアプリまたはデスクトップアプリケーションからキーを送信するとすぐに、キーは他のユーザーに表示されます。

そのキーを送信する必要があるため、アプリ内にキーを安全に保存することはあまり意味がありません。要求に対しては、それは明白でなければなりません。

あなたがするかもしれない一つのことは、あなた自身のウェブサービスまたはラッパーをホストすることです。それはキーサーバー側を追加し、そしてそのリクエストをターゲットサーバーにルーティングします。

ただし、Twitter /または使用しているサービスがIPごとのAPIリクエストを制限している場合や、IPベースの統計を作成したい場合は、これは不可能です。

要約すると、他の人のためにAPIを作成する立場にあり、SSLを使用したくない場合、キーが安全で簡単に盗まれないようにするために、どのような可能性がありますか? ?

34
user510083

ベストプラクティスは次のとおりです。

基本的な考え方。ユーザーアカウントごとにAPIキー(128ビット対称キー)を作成します。このキーはサーバーに安全に保存する必要があり、ユーザーのクライアントにも安全に保存する必要があります。

クライアントからのリクエストごとに、リクエスト全体に「署名」を持つリクエストパラメータを追加します。 「署名」は、S = MAC([〜#〜] k [〜#〜][〜#〜] r [ 〜#〜])、ここで[〜#〜] k [〜#〜]はAPIキー、[〜# 〜] r [〜#〜]は、すべてのリクエストパラメータを含むリクエスト全体です。ここで、MACは、AES-CMACやSHA1-HMACなどの安全なメッセージ認証コードアルゴリズムである必要があります。

署名を計算してリクエストに追加するのはクライアントの責任です。署名を検証し、無効な署名を持つ要求を無視するのはサーバーの責任です。リクエストを行うユーザーアカウントを識別するリクエストに、追加のパラメータを含める必要がある場合もあります。

これにより、要求の認証は提供されますが、機密性や再生防止は提供されず、クライアントはサーバーから認証された応答を受け取ります。

すべてのリクエストをhttpsではなく(httpではなく)送信することをお勧めします。これは、多くのトリッキーなケースに対して追加のレベルのセキュリティを提供します。これを実行することによるパフォーマンスへの影響は、あなたが思うよりも少ない- SSLは、ほとんどの人が考えるよりもパフォーマンスのオーバーヘッドが少ない -したがって パフォーマンスの理由でこのアイデアを破棄しないでください でない限り実際には measured パフォーマンスのオーバーヘッドがあり、許容できないことがわかりました。

追加の注意事項認証済みリクエストのリプレイを防ぐために、1回限りのナンスを使用することができます。暗号強度のランダム値(少なくとも64ビット長)を使用することをお勧めします。 httpsを使用している場合、これは不要です。

サーバーが ホストパラメータ汚染(HPP)攻撃 から守るように記述されていることを確認してください。たとえば、同じタイプの複数のリクエストパラメータ(例:http://example.com/foo.html?name=x&name=y)。また、サーバーコードを作成するときは、受け取った要求に基づいて新しい要求を作成するときに注意してください。たとえば、各要求を処理する前に、サーバーコードは、要求にパラメーターの期待されるリストのみが含まれ、それ以外は含まれていないことを検証する場合があります。リクエストを処理する前に、重複するパラメータまたは予期しないパラメータを破棄します。

メッセージ認証コードで複数の値を保護する場合は、 連結の欠陥 に注意してください。

37
D.W.