web-dev-qa-db-ja.com

サーバーにAPIキーを保存する

ユーザーがそれぞれAPIキーを持っているサービスがあります。キーを保存して、APIリクエストの検証に使用できるようにする必要があります。

キーをデータベースにプレーンテキストで保存している場合、誰かがデータベースにアクセスし、すべてのプレーンテキストのAPIキーを取得し、それらを使用して他のユーザーになりすますシナリオが心配されます(誰かがアクセスした場合、より大きな問題が発生する可能性があります)ただし、dbへ)。

これは、ハッシュを保存してそれを使用して検証するだけのユーザーパスワードの保存と似ていますが、ほとんどのAPIではAPIキーを表示できます。つまり、回復可能な方法で保存する必要があります。

このためのベストプラクティスはありますか?

21
user3203425

誰かがデータベースを取得してキーを取得するという脅威は、APIキーを使用してデータベース内のデータにアクセスできることを意味します。

誰かがデータベースにアクセスしてパスワードを取得できるという脅威は、人々はパスワードを再利用する傾向があるため、同じユーザー名で他のWebサイトでそれらのパスワードを再利用できることを意味します。

パスワードを平文または簡単に元に戻せるもう1つの理由は、社内の誰かがパスワードを入手し、ユーザーとして振る舞う悪質な行為を開始する可能性があることです。 IS APIキーが明確である場合に発生するリスク。

通常、HMACは単一の秘密鍵といくつかの公開値から安全な値を暗号で計算するためのソリューションです。

HMACをご覧ください。 HMACを使用すると、アプリを使用してメモリに秘密鍵をロードできます(構成ファイル、Amazon KMSからの読み取り、アプリの起動時に入力、またはそこにその秘密鍵を取得したい)。

データベースにトークンを格納します。 Token = UUID()など。トークンはユーザーに固有である必要があり、再生成する必要がある場合に備えてトークンをバージョン管理することができ、トークンはランダム(UUIDなど)にすることができます。トークンは秘密ではありません。

APIキーは、秘密キー(SK)とユーザートークン(UT)を使用して次のように計算されます。

API_SECRET = HMAC(SK, UT)

次に、それを配布しますAPI_KEYおよびAPI_SECRETをユーザーに送信し、ユーザーが接続しようとすると、API_SECRET

  1. データベースからユーザーレコードを取得します(おそらく、ユーザーにユーザー名を提供するよう既に要求しています)。
  2. データベースのUTからAPI_SECRETを計算します。

    API_SECRET_DB = HMAC(SK、UT)

  3. 計算されたAPI_SECRET_DBリクエストで提供されたものに:

    if(API_SECRET_DB == API_SECRET_FROM_REQUEST){//ログインユーザー}

結論として、秘密鍵のみを保護し、すべての資格情報を保護するわけではありません。

13
Jonathan