web-dev-qa-db-ja.com

REST apiをメッセージレベルで保護する

次の認証のアイデアについてフィードバックをお願いします。それは理にかなっており、これを行う(または同様の)標準的な方法があるので、十分にテストされた実装に依存できます。

サーバーへの通信をセキュリティで保護する方法については、ここで多くの回答を見てきました。ほとんどの回答は、単にTLSを適切に使用することです。メッセージ自体の暗号化と署名を可能にするソリューションを探しています。そのため、メッセージは宛先サービスに到達するまで、バックエンドを通過しても安全です。

コンテキスト

  • Android 2.3+およびPhoneGapで構築されたiOS 6+用のモバイルアプリ(したがって、使用されるライブラリはJava/obj-cまたはjsから使用できるはずです)
  • アプリはREST json apiを使用してサーバーと通信します
  • メッセージコンテンツは、バックエンドを通過するときに機密情報を保持する必要があります(プロキシ/ロードバランサーでの終了はありません)。
  • 「記憶」をサポートする必要があるため、ユーザーは常にパスフレーズを再入力する必要がありません。
  • すべての通信はssl/tlsを介して行われます

認証

  • クライアントはユーザーの資格情報(ユーザー名、パスフレーズ、および追加のセキュリティ情報)を収集します
  • クライアントは対称鍵を生成します
  • クライアントは、対称鍵を使用して資格情報を暗号化します
  • クライアントはサーバーの公開鍵(クライアントに同梱)で対称鍵を暗号化します
  • クライアントは暗号化されたメッセージ、キー、ノンスをhttps経由で送信します(サーバー証明書の検証)
  • サーバープロキシは認証要求を認証サービスに転送します
  • 認証サービスは対称鍵とメッセージを復号化します
  • 資格情報が有効な場合、サービスは認証トークンを生成します
  • トークンはサーバーの対称キーに関連付けられています。資格情報が無効な場合、リクエストに応答した後、キーは破棄されます
  • 対称鍵で暗号化されたトークンがユーザーに返されます
  • トークンとキーはクライアントにローカルに保存され、短いパスワードで暗号化されます

Tlsが使用されている場合、これらの要求はリプレイ攻撃から安全であるため、攻撃者がメッセージをリプレイして新しいトークンを取得するリスクはありません。

その他のAPI呼び出し

  • クライアントは要求メッセージを生成して暗号化し、暗号化されたメッセージに署名します
  • クライアントは、暗号化されたメッセージ、nonce、および認証トークンを含む署名をサーバーに送信します
  • 受信時に、サーバーは受信したトークンに関連付けられたキーを検索し、署名を検証して、処理前にメッセージを復号化します

質問

  • 同じ対称鍵の再利用に問題はありますか?
  • 対称鍵の適切な選択は何ですか?
    • AES-OCBまたはAES-CBC + HMAC署名についてはどうですか?
  • 対称鍵はどのくらいの頻度で変更する必要がありますか?
  • キー/更新トークンを更新する最良の方法は何ですか?認証応答中に更新トークンを発行し、特定の期間が経過するとキーが期限切れになることを考えていました。そのため、ユーザーがキーを更新しないと、再度ログインする必要があります。

ありがとう

11
Nicolas Esteves

私が何かを見逃していない限り、あなたのソリューションはセキュリティトークンサービスのように見えます。 STSの場合、鍵となるのは、信頼できる当事者が、信頼する当事者の開始当事者を識別することです。あなたの場合、信託ブローカーと依拠当事者は同じエンティティであるように見えます。

信頼を最終的な宛先に伝播させることが目的の場合は、プロキシ経由でSSLを使用し、クライアント証明書を使用してエンドポイントを識別します。トラフィックを検査するためにHTTPがプロキシを通過することを想定している場合、標準のSTSを実装します。

Xanderが言ったように、RESTは軽量のサービス呼び出しに最適ですが、セキュリティを実現したいときはSOAP、特にWS-Security拡張を使用する必要があります。それはそれほど難しくありません。特に、あなたがそうするように両端を制御している場合。これを行う方法については、これを参照してください スタックオーバーフローの質問 AndroidのJava=)。

ホームベークソリューションを続行する場合は、認証の最後の3つの箇条書きが弱点になっていることに注意してください。

5
DodgyG33za

詳細を確認したとは言えませんが、HTTPレベルでメッセージレベルのセキュリティを実装する既存の試みに興味があるかもしれません。例えば:

どちらのプロジェクトもアクティブではないようです。また、他のセキュリティプロトコルが通常持っている、または持っているべきである専門家の精査が欠けている場合もあります。彼らに何か問題があると言っているのではありません。 HTTPsecの成功の欠如は、 "SOAP vs REST wars"(RESTサイド)そしてそれは非フリーライセンスで(Javaで)1つの実装しかなかったという事実。

OpenPGPなどの既存のツールを使用してメッセージエンティティを暗号化および署名することが重要かどうかを調査します。

RESTは、人によって意味が異なるWordです。 SOAPの複数のレイヤーなしで、HTTP上のペイロードを意味する場合もあります。そのようなサービスが実際に HATEOS原則 に従うかどうかは別の問題です。

これに対する私の個人的な意見は、RESTの無国籍性は、必ずしもアプリケーションのセキュリティの側面ではなく、アプリケーションのコア機能に適用する必要があります。もちろん、防止することは(不可能ではないにしても)非常に困難です。受信者側でなんらかの状態を維持せずに攻撃を再生します。

とはいえ、純粋なメッセージレベルのセキュリティに関心があるかどうかは、質問からわかりません。むしろ、クライアントからバックエンドへの直接TCP接続を実行できないため、HTTP経由でSSL/TLSに相当するものをトンネリングすることに主に関心があるようです。 SSL/TLSも使用しています。これは、ロードバランサーを信頼していないことが主な理由であることを示しています。独自のプロトコルを作成することは一般的に難しく、多くの場合悪い考えです。暗号化とMACアルゴリズムに関する推奨事項は、 (比較すると、TLSのいくつかの問題が特定されて対処されるまでにはしばらく時間がかかりましたが、詳細な仕様を備えたオープンなプロトコルであり、多くの専門家によって研究されています。)

3
Bruno