web-dev-qa-db-ja.com

ユーザーが非常に少ないバックエンドWebサービスでのAPIキーの検証

私はこのシナリオに数回遭遇しましたが、私が正しい軌道に乗っていることの確認、または他に何をすべきかについての提案を得ることを望んでいます。

状況

機密データまたは特権操作へのアクセスを提供するバックエンドWebサービスを構築しています。このWebサービスは一般にはアクセスできませんが、フロントエンドアプリケーションから呼び出されます。最終的には、サービスにアクセスする必要があるが、必ずしも異なるレベルのアクセスではない複数のアプリケーションが存在する可能性があります。

ネットワーク上の他のデバイスがサービスを呼び出したり、トラフィックを傍受して認証方法を決定したりできるように、Webサービスを保護したいと考えています。

解決

基本認証を介して送信される、安全に生成された大きなランダムAPIキーを使用して、ユーザー名とパスワードが分離され、パスワードがSHA-256でハッシュされ、その結果がユーザーの保存された値と比較されます。これはTLSを介して(つまり、ピン留めされた自己署名証明書または有効なCA署名証明書を使用して)行われ、スニッフィングを防ぎ、クライアントがサーバーの信頼性を検証するようにします。

パスワードは大きな(128ビットとしましょう)ランダムな値なので、値をハッシュする目的は主に次のとおりです。

  1. WebサービスにAPIキーを保存しないようにするには
  2. 実際のAPIキーがアプリケーションによって実際に格納されている場合、実際のAPIキーとの文字列比較によるタイミング攻撃を防ぐため

追加の考え

私はより一般的なパスワードハッシュ方式(Argon2など)を実行することを検討しましたが、パスワードは人間が読めるように意図されていないため、あまり得られないようです。可能なAPIキーのスペースが非常に大きいため、値をソルトしたとしても、それほど価値があるとは思えません。

これはすべてのリクエストで送信されるため、これを高速に保つ必要があることも明らかであり、あまり多くの処理を行うことは望ましくありません。

また、この方法は非常に単純なので、これが十分に安全である場合は、別の方法を実際には探していません。私は本当に、このスキーマに加えることができる改善点、またはそれが完全に安全ではない理由のどちらかを探しています(その場合、代替案について喜んで聞きます)。

1
thesquaregroot

前提の明確化

コメントでいくつかの明確な質問をしました。次のことを前提に答えます。

  1. バックエンド内のトラフィックはプレーンテキストです(TLSなし)。
  2. APIキーは基本認証フィールドにプレーンテキストで送信され、格納された値と比較するためにのみサーバーによってハッシュが実行されます。

ハッシュとソルト

私はこの声明に完全に同意します。

私はより一般的なパスワードハッシュ方式(Argon2など)を実行することを検討しましたが、パスワードは人間が読めるように意図されていないため、あまり得られないようです。可能なAPIキーのスペースが非常に大きいため、値をソルトしたとしても、それほど価値があるとは思えません。

うん。ソルトは、エントロピーが非常に低いパスワードを選択する人間に対する答えです。 128ビットのエントロピーを持つAPIキーはソルトを必要としません。SHA-256の1回の反復でキーを覆い隠すのに十分です。


スニフ保護

私があなたの質問を理解している方法で、それはおそらくスニフ保護を取得していません。つまり、バックエンドネットワークトラフィックを盗聴できる誰かがAPIキーをHTTP要求から引き上げることができるようです。

提案1:client-auth TLS

私の最初の提案は、フロントエンドサーバーをTLSクライアント証明書(およびローカルに格納された秘密キー)でセットアップすることです。バックエンドサーバーでフィルターを記述して、クライアントが期待するクライアント証明書を提示したことを確認します(クライアント証明書の検証の実装にはガチャがいくつかありますが、この質問の範囲を超えています)

とはいえ、あなたの説明から、TLSはCPUを使いすぎるように思えるかもしれません。

提案2:チャレンジ/レスポンス/ゼロ知識証明

別の言い方をすると、「ネットワーク経由でAPIキーを送信せずに、フロントエンドサーバーがAPIキーを認識していることを証明する必要があります」

これはゼロ知識証明の定義と非常によく似ています[ wikipedia ]:

ゼロ知識証明の本質は、単に特定の情報を明らかにすることによって特定の情報の知識を持っていることを証明することは簡単であることです。課題は、情報自体または追加情報を明らかにせずに、そのような所持を証明することです。

(しかし、私が間違っていることを証明するコメントの準備ができています)バックエンドにソルトを送信させることでインタラクティブなZKPを実行できると信じています(おそらくAPIキーと同じ長さ)、フロントエンドはAPIキーのソルトハッシュを送り返します。

ZKPの詳細については、ウィキペディアを参照してください: https://en.wikipedia.org/wiki/Zero-knowledge_proof

2
Mike Ounsworth