1

私は、Amazon S3 REST 認証とほとんど同じように機能する REST 承認サービスを設計しました。これは、HTTP で動作するのに十分安全です (すべての相互通信を SSL で実行するためのオーバーヘッドを必要としません)。

署名はリクエストごとに変更され、有効期限があるため、十分に安全です。そのため、MITM (何も編集できないため、エンドポイントは同じ署名を再生成できません) やリプレイ攻撃 (タイムスタンプの使用のため) に対して安全です。

これは、秘密鍵を知っているすべてのクライアントにとって良いことであり、要求データを含む一意の署名を生成する独自のデータに対して要求されたアクションを実行できるようになりました。

承認サービスはトークンを生成せず (そのため、MITM 攻撃の対象となることはありません)、内部的にのみ呼び出されます。つまり、クライアントは、トークンを要求する代わりに、特定の操作を実行するために適切なエンドポイントに直接要求を実行します。そのサービス...その後、そのリクエストを受信したエンドポイントは、「ねえ、これは正当なリクエストですか?」と尋ねる認可サービスへのクエリを作成します。その場合、承認サービスは「200 OK」を返し、サービスは要求された操作を実行します。それ以外の場合は、「401 Unauthorized」を返します。

私が今必要としているのは、特別なクライアントである Web ユーザー インターフェイスが、ユーザーに電子メール/パスワードを使用してログインさせ、WebUI 自体を使用してデータを取得/編集できるようにすることです。webUI は HTTPS で実行されます。新しいアカウントを作成すると常に user/pwd ログインと pubkey/privatekey の両方が生成されることを考慮してください。ただし、実際には pubkey/privatekey のみを使用しています。ユーザーと pwd は、WebUI のみが使用するデータベース内に格納されますが、pubkey/privatekey は (別の DB を使用する) 承認サービス内に格納されます。

もちろん、顧客データを操作するには、WebUI がログに記録されたユーザー (署名を生成するための pubkey/privatekey に関連付けられたペアを持つ) 用に作成されたクライアントとして動作するようにする何らかの方法が必要です。これを行う最も安全な方法がわからないので、私が考えたいくつかの解決策を説明します。

私が考えた最初の解決策は、Web インターフェイスに独自の pubkey/privatekey を与えて実際のクライアントにし、承認サービスを編集してそれを認識し、公開鍵 (承認サービスで取得できる) を送信できるようにすることです。 "X-Forwarded-For" のようなヘッダー) を使用し、常に webUI 権限を信頼します。しかし、どういうわけか、この権限を悪用して権限のないデータを取得する攻撃につながる可能性のある何かを見逃しているのではないかと心配しています.

2 番目の解決策は、ログインに成功したら、pubkey/privatekey の両方を Authorization Service から WebUI に転送し、WebUI がそれをセッション内に保存し、アクションが実行されるたびにそのデータを使用して有効な署名を生成することです。しかし、私はこれらのデータをネットワーク経由で渡すのはあまり好きではありません (また、秘密鍵が傍受されるのを避けるために、この通信は少なくとも SSL 経由で行う必要があるため)。また、秘密鍵をセッション バックエンド内に保存するのも好きではありません。 .

私が考えた最後の解決策は、承認サービスを再考し、ユーザーとパスワードによる認証も許可することです (これは webUI 内に保存されるのではなく、承認サービス内で pubkey/privatekey と一緒に保存されます)。WebUI は電子メールとパスワードを通信する必要があるため、これには常に SSL 接続が必要ですが、正しくログに記録された場合、作成されたセッション内にそれらのデータしか保存できません。もう 1 つの副作用は、署名メソッドを使用する代わりに user/pwd を使用するように他のサービスを実装できることです。これは、HTTP を介してデータを世界中に公開することを意味します。

アーキテクチャ全体がクライアントサーバーベースで動作すると考えられているため、webUI をクライアントとして機能させる、最強でより論理的なソリューションが必要です。ここに記載されていない他の提案も受け入れることができます。

私を助けるためにもっと知る必要があるかどうか教えてください。

ありがとうございます (投稿全体を読んだ場合:-P)

4

1 に答える 1

0

HTTPS

まず第一に、あなたはすべての HTTPS のことを誤解していると思います。HTTPS を使用すると、クライアント証明書を提供できますが、最も一般的なケースでは、サーバー証明書のみが使用されます。したがって、この一般的なケースでは、HTTPS はユーザーを認証する方法を提供せず、サーバー自体のみを提供します。また、メッセージの暗号化も提供します。

HTTP を使用している場合、実際の MITM 攻撃から保護できたとしても、MITM はすべてのメッセージを表示します。それらが非公開にされない場合 (一部の個人データなど) は、おそらく問題ありません。

もう 1 つのことは、サーバー自体の認証です。あなたが指定したデータから私が見ることができる限り (一部が欠落しているか、誤解している可能性があります)、すべてのリクエストは署名されていますが、応答は署名されていません (または署名されています)。この場合、攻撃者が認証サーバーになりすます可能性があるため、MITM 攻撃に対して脆弱です。

サーバーの認証には HTTPS を使用し、クライアントの認証にはメッセージと署名のエンコードを使用することをお勧めします。また、MITM 攻撃を防ぐために、ルート CA 証明書を使用してサーバー証明書もチェックする必要があることに注意してください。

秘密鍵

クライアントへの秘密鍵を開始する方法がよくわかりません。技術的には - はい。ただし、秘密鍵は非公開にする必要があります。それらを生成すると、プライベートではなくなります。この場合、共有シークレットを生成し、より単純なアルゴリズムを使用してリクエストに署名できます。少なくとも私の意見では、両方のキーが共有シークレットよりも安全ではないことがわかっている場合は、PPK を使用します。

これを行う別の方法は、クライアントが生成後に公開鍵をサーバーにアップロードできるようにすることです。

パスワード

私の意見では、認可サーバーは認可に関するすべての決定を行うべきです。したがって、UI 部分ではなく、認証サーバーにパスワードと公開鍵 (または共有秘密鍵) を保存します。

結論

あなたの状況はOAuth2 protocolを思い出させます。リソースオーナー、クライアント、認可サーバー、リソースサーバーがあります。リソース所有者は何らかの方法でクライアントにアクセスを許可し、クライアントはその許可を提供する認可サーバーからアクセス トークンを取得します。次に、それを使用してリソース サーバーにアクセスします。

システムで使用できる許可タイプは 2 つあります。リソース所有者パスワード資格情報許可とクライアント資格情報許可です。

  • リソース所有者はクライアント自身です。
  • UIもクライアントです。
  • UI は、クライアントのパスワード資格情報を提供してアクセス トークンを取得し、リソース サーバーを呼び出します。
  • クライアントは、共有秘密鍵または公開鍵を使用して自分自身を認証するだけで、アクセス トークンを取得します。

もちろん、プロトコルがあなたのケースに完全に適していない場合は、プロトコルからいくつかのアイデアを得ることができます.

リクエストの署名に関しては、同じ OAuth2 で使用できるMAC アクセス認証があります。

したがって、パスワードを認証サーバーに保存することをお勧めします。UI はそれらを渡して一部のリソースを変更します。クライアントの秘密鍵を生成しないでください。共有秘密鍵を使用するか、公開鍵をアップロードさせてください。リモート サーバーの認証には HTTPS を使用します。

于 2013-01-05T12:48:40.417 に答える