2016-07-21 8 views
3

MVCベースのサーバーアプリケーションを移行し、呼び出しを処理するREST-ful APIを作成中です。OAuth:JavaScriptの秘密キーを非表示にする方法

私はAES暗号化とのOAuth2上に読んで、次のように成長ソリューションは、これらの概念を形成し実施することを決定してきた:

  1. クライアントは、ユーザーIDやメールを提供してログインするための要求を送信します。この要求は、API秘密鍵を使用してHMACされます。
  2. サーバーは、ユーザーID /電子メールが既存のアカウントと一致するかどうかを調べ、見つかった場合は、クライアントの応答の一部として送信するサーバーナンスを作成して保存します。
  3. クライアントは独自のクライアントナンスを作成し、API秘密鍵と両方のnoncesから新しい一時キーを作成します。次に、この一時的なキーを使用して暗号化されたパスワードを持つログイン要求を送信します(エントロピーを追加し、平文でパスワードを送信することを避けるため)。
  4. サーバーは、このプラットフォームでこのクライアント用に保存した最新のnonce [モバイルとWebクライアントは独自の固有のセッションとセッションを持つことができます]と、暗号化されていない状態で送信されたクライアントnonceを使用して、 HMACがチェックアウトすると、データベース[PBKDF2のハッシングとソルト]に対してパスワードが検証されます。
  5. 要求が有効で、パスワードとユーザーIDがレコードと一致する場合、そのプラットフォーム上のそのユーザーID用に新しいセッション秘密キーが作成され、この秘密キーがクライアントに送信され、HMACは、それ以降。
  6. 新しいログインではないリクエストには、セッションシークレットキーとランダム化されたIVから計算されたHMAC署名が含まれます。

すべての通信はTLSによって処理されるため、セキュリティが強化され、唯一の防衛線ではありません。

モバイルアプリでは、モバイルアプリの秘密鍵を設定ファイルに隠すことができます。これはセキュリティの適切な指標を提供します。[多分多くはわかりませんが]私たちのウェブページからのすべてのリクエストをこのフォームに変換すると、これはJavaScriptを使用してクライアント側のAES暗号化と認証を処理することを意味します。well as this article clearly explains "JavaScriptのWebアプリケーションにAPIキーを保存すると、世界全体がブラウザの開発ツールを使ってアクセスできるように、ホームページ全体に大きな太字で書かれている」と語った。

API秘密鍵としてナンスだけを使用することもできますし、これらのリクエストにAES暗号化を使用しないでもかまいません。また、CSRFトークンなどの他の手段で検証し、すべてのリクエストが私たち自身のフロントエンドいくつかの方法 - しかし、私たちが他のページやサービスとの統合を可能にするAPIを作成したいのであれば、これはうまくいかないでしょう。

この記事では、使い捨てのクッキーをトークンとして生成することを提案していますが、それはポスターのサービスには適しているが、私たちにとってはそうではない限定的な解決策です。私は、ユーザーが期限切れでリセットすることができるユーザー固有のキーを使用してユーザーが送信するすべてのリクエストをHMACに送信したいと考えています。サービスが最終的にお金を処理するため、リクエスト認証を厳重に保護します。

私のオプションは何ですか?

is doomedからJavascriptを削除するだけですか? .jsスクリプトにハードコードされた日に秘密鍵を保存する方法はありますか?ログインの呼び出しにのみ使用する新しい一時的な秘密鍵を生成して、サーバーのnonceを要求したときにユーザーに送信する必要がありますか?

また、最初にリンクしたポストは、クッキーを使用してクライアントのセッションキーを保存し、次にJSからキーにアクセスすることを示唆しています。これは大丈夫ですか、それはシールよりも多くの穴を提供しますか?

答えて

1

どのような対策がどのセキュリティホールを防いでいるかを知ることは良いことです。

秘密を保存する場所がないため、JavaScriptは暗号化にはあまり適していないということは間違いありません。 JavaScriptで暗号化を行うべきではないので、良い暗号化ライブラリもありません。

セッションキーを認証キーとして使用できます。 TLSを使用している場合、接続は安全であり、攻撃者はセッションキーを知ることができません。 さらに、JavaScriptはセッションキーを知る必要はありません。デフォルトでは、Cookieはすべてのリクエストとともに送信されます。また、Cookieをhttp専用のCookieに設定することもできます。 にはが必要ですが、別のセキュリティ層が追加されます。

セッションクッキーに非常に長い有効期限を与えて、基本的に秘密のAPIキーのように動作させることができます。ブラウザはCookieを安全に保管します。新しいセッションが始まるときや認証情報が変更されたとき(パスワードリセットなど)にセッションキーを頻繁に回転させることをお勧めします。

CSRFトークンはリプレイ攻撃を防止します。 CSRFトークンを使用して変更要求を保護することをお勧めします。すべての要求に対してCSRFチェックを行う必要はなく、機密情報(ログイン資格情報など)を変更する要求や、場合によってはトランザクションが必要になります。 CSRFトークンについては、セッションキーと同じ方法を使用できます。クッキーに格納します。

重要な点は、JavaScriptがこれについて何も知る必要がないことです。

あなたが実現すると確信している重要なことの1つは、生成する鍵やナンスが暗号的に安全でなければならないということです。低エントロピー関数を使用しないでください。だから、

:あなたはユーザーIDまたは電子メールを暗号化する必要はありません

  1. 、TLSはすでにあなたのためにそれを行います。さらに、パスワードを送信することもできます。手順3で個別に送信する必要はありません.JavaScriptでは暗号化を行いません。すべての暗号化は、TLS/HTTPSだけで処理されます。

  2. 別の認証サーバー(シングルサインオンなど)を使用している場合、この方法は問題ありません。そうでなければ、このステップをスキップすることができます。

  3. これは必要ありません。

  4. サーバは何かを復号化する必要はなく、暗号化はTLSによって処理されます。どのようにパスワードを保存するのかは、自分の話題ですが、私はあなたがそれを持っていると思います。

  5. 再び、クライアントは何も暗号化すべきではありません。

  6. セッションキーのみを送信します。それで十分です。改訂

は次のとおりです。

  1. クライアントは、ログイン資格情報を送信します。接続は安全でなければなりません。

  2. サーバーは、資格情報を確認し、認証トークンをクッキーとして送信し、認証トークンの追跡をセッションリストに記録します。

    • クライアントが認証トークンが含まれています。すべての要求については

。これは、Cookieを使用すると自動的に発生します。

  • サーバーは認証トークンを検証し、その後クライアントが使用する新しいトークンを生成する可能性があります。

  • +0

    クライアントがセッションキーをクッキーとして取得し、それを送信すると、HMAC署名が必要ないと言っていますか?改訂された認証パターンを使用してリプレイ攻撃から保護する方法を教えてください。 – ConnorU

    +0

    CSRFトークンは、再生攻撃を防ぎます。 1.クライアントは '/ change_password'を要求します2.サーバはCSRFトークンを作成し、それをトークンリストに保存します(妥当な有効期限があります)。それにはCSRFトークンが含まれています。 (例えば 'action ="/do_password_change?csrf = [token] "の形式で)3.クライアントがCSRFトークンをリクエストとともに送信する4.サーバがCSRFトークンをチェックし、それをトークンリストから削除するこれにより、CSRFトークンの2回目の使用で不正なリクエストが発生する(サーバはそれが使用されていることが分かっているため)リプレイ攻撃を防ぎます。 – Halcyon

    +0

    私はCSRFのビットを読んでいます。誰かがより多くのインプットやアイデアを持っている場合に受け入れられます。ありがとう! – ConnorU

    1

    モバイルアプリはpublic clientsと見なされます。つまり、秘密を保管してはいけません。使用する暗号化アルゴリズムが何であれ、クライアントの資格情報が侵害されることはありません。

    OAuth2 Frameworkプロトコルは、公開クライアントとのやり取りを許可し、クライアント認証を必要としないImplicit grant typeフローを定義しています。また、アクセストークンの発行を保護するためにRFC7636と考えることもできます。

    関連する問題