web-dev-qa-db-ja.com

Google APP Engineの証明書によるクライアント認証java

私はGoogle APP Engineでアプリケーションを書いていますJavaこれは証明書でユーザーを認証します。クライアント側でkeytoolを使用して自己署名証明書を作成しました。GoogleアプリエンジンでHTTPSリクエストも有効にします私のアプリケーションでは、アプリケーションのフローは非常に簡単です。

ユーザーがブラウザーを使用してアプリケーションのホームページにアクセスし、アプリケーションのリソースにアクセスしようとすると、有効な証明書があればユーザーを認証します。ユーザーが任意のブラウザーでアプリケーションにアクセスしたときに、クライアント側で作成したこの証明書がアプリケーションに送信される方法が欠けていますか?また、証明書を検証するにはどうすればよいですか?

2
Waqas Ali

GAEで相互SSL/TLSハンドシェイクを使用してクライアントを認証できないと思います。

Java EEでこれを実現するには、これをweb.xml

<login-config>
    <auth-method>CLIENT-CERT</auth-method>
</login-config>

ソース: https://docs.Oracle.com/javaee/6/tutorial/doc/glien.html

ただし、AppEngineのドキュメントは言う:

App Engineはカスタムセキュリティロール(<security-role>)または代替認証メカニズム(<login-config>)デプロイメント記述子内。

ソース: https://cloud.google.com/appengine/docs/Java/config/webxml#Security_and_Authentication

2
toni77

ユーザー証明書のポイントは、ユーザー側にstoredがあるもの、特にuser private key。認証用の証明書はSSLの一部として使用されます(HTTPSはSSL内のHTTPです)。

SSLでは、次のようになります。

  • クライアントが接続します。クライアントとサーバーは互いに通信します。
  • サーバーは彼の証明書(サーバーの公開鍵を含む)を表示します。クライアントは、証明書が有効であること(クライアントが信頼するCAによって適切に署名されていること、目的のサーバー名が含まれていること、有効期限が切れていないことなど)を確認し、サーバーの公開鍵を使用して、そこから派生した非対称鍵交換を行います後続のデータフローを保護するために使用されるセッションキー。
  • サーバーはclient証明書を要求する場合があります。その場合、クライアントは証明書(クライアントの公開鍵を含む)を送信し、対応する秘密鍵の習得を実証する必要があります。

これらの手順はすべてSSLプロトコルで行われ、実行させるだけです。ただし、サーバーでの仕事は、クライアント証明書をvalidateすることです。それは何ですか ?証明書自体は何も証明しません。実際、誰でも任意の内容の自己署名証明書を作成できます。あなたは自分でやっただけです。証明書が役立つのは、そもそも証明書がどのように生成されたかです。

あなたの場合、主に3つの可能性があります:

  1. サーバーにはすべてのユーザー証明書(秘密鍵ではない)のコピーがあるため、受信した証明書をすべての既知のユーザー証明書と比較できます。したがって、証明書は、既知の証明書とビット対ビットであることによって検証されます。証明書はクライアント側で作成されたため、ユーザーがサーバーに証明書を提示する最初の登録フェーズが必要です。

  2. サーバーがユーザーに証明書を発行します。これは、証明書を作成するために、ユーザー側の一部のコード(たとえば、ブラウザー内)が秘密鍵と公開鍵のペアを生成し、公開鍵をサーバーに送信し、サーバーがそれを新しい証明書に入れて、ユーザー名とサーバーが署名します。結果の証明書はユーザーに送り返されます。後でユーザーが接続すると、サーバーはサーバー自体によって署名されているため、サーバーはユーザー証明書を認識します。サーバーは独自の公開鍵を使用してユーザー証明書の署名を確認します。その署名が有効な場合、サーバーは証明書の内容、特にユーザー名が信頼できることを認識しています。

  3. 証明書の発行が Certification Authority と呼ばれる別の専用システムに委任されることを除いて、状況2と同じシステム。ユーザーはサーバーをまったく使用せずに、CAから証明書を取得します。サーバーは、CAによって適切に署名されていることを確認することにより、ユーザーが送信した証明書を検証できます。サーバーにはCAの公開鍵のコピーがあり、適切に認証されたユーザーにのみ証明書を発行するためにCAを信頼します。

3番目のケースだけが実際に意味があります。証明書は、(CAによる)IDのアサーションが、(サーバーでの)IDの使用から切り離されている状況で役立ちます。サーバー自体がCAの場合、証明書を使用しても、単純なパスワードベースの認証に勝る利点はありません(「パスワード」は、ブラウザーによって自動的に保存される長いシーケンスである可能性があります。これは cookie と呼ばれます。 )。

それでも証明書を使用することに意欲がある場合は、最初にCAとは何か、CAの機能、およびシステム内のCAがどこに適合するかについて頭の中で明確にする必要があります。

2
Thomas Pornin

ユーザーに認証用の有効な証明書を提示させるには、事前にそのユーザーに自己署名キーに基づいてその証明書をプロビジョニングする必要があります。問題名の抽出に関するコメントに基づいて、ユーザーに事前に上記の埋め込み名(およびルートでの自己署名キー)を提供する証明書を生成するには、認証局(CA)を確立する必要があるようです。

通常、このタイプのプロビジョニングは扱いにくく、Webの全体的なエクスペリエンスに反します。したがって、戦略は使用されず、ブラウザーはそれをサポートするように設計されていません。これらの線に沿って続行したい場合は、証明書によってSSHを認証する方法を検討することを検討してください(PKI公開鍵と秘密鍵を使用しますが、CA信頼チェーンは使用しませんが、方法を理解することはまだ啓蒙的です)。

繰り返しになりますが、ユーザーのブラウザはこの証明書を提供するように設計されていないため、サーバーにアップロードする機能を提供する必要があります。名前の検証と抽出については、Javaには、すでに使用しているkeytoolを提供する機能に必要なルーチンがあります。

0
zedman9991