19

Javaキーストアに2つの証明書/キーペアがあります。これらのキーエントリのエイリアスは「foo」と「bar」です。

私のTLSクライアント(Javaプログラム)はキーストアを使用しています。TLSクライアント認証は、接続の開始時に行われます。クライアントプログラムは、TLSサーバーがクライアントに証明書を要求するときに「foo」キーエントリを使用する必要があります。これで、クライアントは接続ハンドシェイク中に間違った証明書(「バー」)をサーバーに送信します。

接続する前に、SSLSocketへの必要なキーエントリのエイリアスを確認するにはどうすればよいですか?

現在、コードは次のとおりです。

final SSLSocket ss = (SSLSocket)SSLSocketFactory.getDefault().createSocket(); 
ss.setEnabledProtocols( new String[] {"TLSv1"});
ss.connect( targetAddress ); 
4

1 に答える 1

28

デフォルトKeyManagerでは、サーバーによって要求された条件に一致する最初の証明書が送信されます。つまり、要求中にサーバーによって送信されたCA名の1つに証明書チェーンを構築できる最初の証明書が送信されます。 。

常に特定のエイリアスを選択する場合は、独自のエイリアスを実装する必要がありますX509KeyManager。デフォルトのマネージャをラップすることもできます。これらの線に沿った何かが機能するはずです(この実際のコードはテストされていません。いくつかのタイプミスがある可能性があります)。

KeyStore keystore = ... // create and load your keystore.

KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(keystore, password.toCharArray());

final X509KeyManager origKm = (X509KeyManager)kmf.getKeyManagers()[0];

X509KeyManager km = new X509KeyManager() {
    public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) {
        return "foo";
    }

    public X509Certificate[] getCertificateChain(String alias) {
        return origKm.getCertificateChain(alias);
    }

    // Delegate the rest of the methods from origKm too...
}

次に、それをあなたのSSLContext:に使用します

SSLContext sslContext = sslContext.getInstance("TLS");
sslContext.init(new KeyManager[] { km }, null, null);
SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
于 2013-03-04T13:25:27.790 に答える