私はいくつかの関連する質問を読みましたが、それらのどれも本当に私を助けません。それでは、少し背景を説明しましょう。私は、登録、投票カードの交換、および投票を管理するサーバーが2つある投票システムを作成しています。登録ユーザーが個人データを送信する間、サーバーはデータがデータベース内のデータと一致するかどうかを確認し、ユーザーの証明書を受け入れて、次のようにトラストストアに追加します。
KeyStore.Entry entry = new KeyStore.TrustedCertificateEntry(cert);
trustKeyStore.setEntry(alias, entry, null);
次に、trustStoreをファイルに保存します。登録中に多くのユーザーが証明書を登録してから、クライアントとサーバーの両方の認証を要求する別のサーバーに接続すると、ここで問題が発生します。この「他のサーバー」は前述のtrustStoreを使用してユーザーとSSLHandshakeを実行できると思いましたが、trustStoreは「最後に登録したユーザーのみを記憶しているようです」。私は次のようにSSLServerSocketを作成しています:
tmf.init(trustKeyStore);
kmf.init(keyStore, password);
// create, init SSLContext
SSLContext sslCtx = SSLContext.getInstance("TLS");
sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
// create SSLSocketFactory and SSLSocket
SSLServerSocketFactory sslSocketFactory = (SSLServerSocketFactory)sslCtx.getServerSocketFactory();
sslSocket = (SSLServerSocket)sslSocketFactory.createServerSocket(1234);
前に述べたように、両側認証は正常に機能しますが、trustStoreの最後のエントリに対してのみ機能します。それで、最後に私の質問は-ユーザーごとに個別のtrustStoreを作成する必要がありますか?TrustManagerをオーバーロードする必要がありますか?基本的に、SSLContext / SSLEngineですべての信頼できる証明書を反復処理し、一致する証明書が見つかった場合にハンドシェイクを実行する方法はありますか?
アップデート
いくつか明確にする必要があると思います。まず第一に、これはWebアプリケーションではなく、通常のクライアントサーバーJavaSwingアプリです。使用されるすべての証明書(サーバーまたはクライアント)は自己署名されていますが、サーバーの証明書はクライアントアプリケーションに組み込まれているため、クライアントがサーバーに接続すると、証明書を比較できます(機能します)。ブルーノが提案したのとまったく同じように解決しようとしました。ユーザーが登録した後、サーバーはデータが有効かどうかを確認し、有効な場合はクライアントに新しい証明書を発行し、トラストストアに追加してクライアントに送信します。しかし、それは最後に登録されたクライアントでも機能しませんでした。