私はREST APIを開発しました。これはHTTPSでのみ動作するように構成されています。このAPIの唯一の目的は(現時点では)モバイルアプリケーションのバックエンドエントリポイントとして動作することです) 。
クライアント認証に使用する独自のトークン認証プロトコル( この質問/回答を参照 )を公開しました。この背後にある主な理由は、クライアントがローカルに保存し、後続のリクエストで再利用できる安全で再利用可能なトークンを生成できることでした。私はこれらのトークンをサーバー側で制御しているため、期限切れ/無効化してクライアントに再認証を強制する(つまり、新しいトークンを生成する)ことができ、MitM /リプレイ攻撃などを回避するための予防策も講じています。これが機能するためには、いくつかの機密情報がプレーンテキストでネットワークを介して渡される必要がありますが、すべてがSSLで実行されているため、AFAIKではここで心配する必要はありません(?)。
この現在のセットアップには、私に関係のある部分がいくつかあります。
サーバー認証の場合、アプリがサーバー証明書(自己署名)を受信すると、証明書のサブジェクト(CN = domainnameなど)がAPIアドレスと同じかどうかのみを確認しています。つまり、APIエントリポイントがapi.mydomain.comの場合itmustサブジェクトCN = api.mydomain.comの証明書を受信する必要があります。そうでない場合、SSLセッションは失敗します。
匿名リクエストからのサーバーの観点からの保護はありません。クライアント認証は、ヘッダー/投稿情報が検査された時点でのみ発生します。これにより、Dos攻撃への扉が開いたままになる可能性があります。理想的には、サーバーがknownソースからのリクエストのみを受け入れるようにしたいです。
最初の問題に関する私の懸念は、回避するのが非常に簡単であり、APIアドレスはアプリの設定から構成可能であり、誰もが自己署名証明書を生成できるため、アプリをだまして正しいサーバーと通信していると思わせるのはかなり簡単です。 2番目の問題はより一般的な問題にすぎませんが、認証されていないクライアント要求を除外できればおまけになります。
解決するために思い浮かぶ唯一のこと(少なくとも2番目の問題)は、クライアント証明書を導入することです。これに対する私の懸念は、実装時間、導入の複雑さと証明書自体の管理です。私が探しているのは、(現在の設定に基づいて)デバイスにクライアント証明書を導入すると、ここに何かゲインが得られるかどうかに関するアドバイスでしょうか?
Authenticationは、接続の反対側にいる人が、あなたが彼であると信じている人であることを確認することについてです。これは暗号化とコンピューターおよびネットワークであるため、「あなた」とは「あなたが計算できること」(リモートサーバーから観察できるすべて)に相当し、それ自体は「あなたが知っていること」に由来します(誰でもPCを購入できます)。したがって、何かを計算する機能は、実際には計算のための入力に関する知識です。たとえば、パスワードベースの認証の場合、ユーザーはパスワードに関する知識に基づいて認証されます。
そのような知識は最初のregistrationにリンクされており、秘密の値は、それが何であれ、特別な意味を持ちます。さらにパスワードの例については、これはユーザーが自分のパスワードを選択する手順であり、サーバーはそれを内臓に記録します(またはそのハッシュ)。
証明書は、registrationおよびauthentication別個のエンティティによって行われます:登録はCertification Authorityによって行われ、クライアントはクライアント証明書を発行(署名)しますが、検証は証明書を検証し(CAからの署名を検証)、次にクライアントによって計算された新しい署名を検証するサーバー自体(SSLでのクライアント証明書の使用方法)。
サーバーが1つだけあり、どちらが接続するかを決定し、次にこれらのクライアントを認証する場合、クライアント証明書は役に立たない:より単純なパスワードの表示プロトコルに関する追加の機能やセキュリティは提供されません( 「パスワード」が十分なエントロピーを持つキーであり、プロトコルがSSL内で再生される限り)。