web-dev-qa-db-ja.com

APIキーはどのように生成する必要がありますか?

リクエストが偽造されてサーバーに送信されないようにする必要があります。これを行うには、システムでユーザーごとにAPIキーを生成する必要があります。キーの目的は、クライアント側でリクエストに署名し、サーバーでリクエストを検証することです。

問題は、一般にAPIキーは何で構成されているかということです。それらは暗号的に安全な乱数(パスワードソルトに似ています)ですか?または、それらの背後にいくつかのロジックがありますか?それらがユーザー固有のデータで構成されている場合。

私のシステムでは、各ユーザーはすでに公開されていない一意のID(GUID)を持っています。これを「キー」として使用できますか、それともAPIキーがユーザーIDと異なる必要がありますか?

31
James

役割をどの程度分離したいかによります。

基本システム:「署名」は [〜#〜] mac [〜#〜] です。 「APIキー」は、サーバーとユーザー間で共有される秘密の値です。 [〜#〜] hmac [〜#〜] のような通常のMACアルゴリズムは、任意のビットシーケンスをキーとして使用できるため、_/dev/urandom_(Linux、* BSD、 MacOS X)、CryptGenRandom()を呼び出す(Win32)、または_Java.security.SecureRandom_を使用する(Java)。

拡張システム:あなたの署名は本当です デジタル署名 。これは、キージェネレーター(サーバーが受け入れるキーを生成できる)をサーバー自体(受信署名を検証する)から分離する場合に意味があります。署名アルゴリズムの鍵は、多くの内部構造を持つ数学的オブジェクトであり、各アルゴリズムは特定の鍵生成アルゴリズムを意味します。必要なビットをすでに実装しているライブラリを使用します(例: OpenSSL )。


どちらにしても、鍵の生成と署名だけではありません。たとえば、リプレイ攻撃を回避したい場合があります。悪意のある第三者がネットワークをスパイし、通常のユーザーが署名した有効なリクエストを記録します。その後、攻撃者は再度そのリクエストを送信し、そのシグネチャを完成させて、効果を再現します。リプレイ攻撃を回避するには、何らかの外部プロトコルを追加する必要があり、これらのことは実行が困難です(プロトコルを定義することは難しくありません。定義するのは非常に困難ですsecureプロトコル)。したがって、賢明なことは、実際に SSL/TLS を意味する、十分に吟味された既存のプロトコルを再利用することです。

SSLを使用すると、「基本システム」は、会話の開始時にヘッダーでAPIキーを送信するように削減されます(これは、HTTPS Webサイトでのパスワード認証の場合とまったく同じです)。その場合、「拡張システム」は「クライアント証明書を使用したSSL」です。

24
Thomas Pornin