在同一主机上使用 Java 中的多个 SSL 客户端证书

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/889406/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 14:14:40  来源:igfitidea点击:

Using multiple SSL client certificates in Java with the same host

javasslcertificate

提问by cwick

In my Java application, I need to connect to the same host using SSL, but using a different certificate each time. The reason I need to use different certificates is that the remote site uses a user ID property embedded in the certificate to identify the client.

在我的 Java 应用程序中,我需要使用 SSL 连接到同一台主机,但每次都使用不同的证书。我需要使用不同证书的原因是远程站点使用嵌入在证书中的用户 ID 属性来识别客户端。

This is a server application that runs on 3 different operating systems, and I need to be able to switch certificates without restarting the process.

这是一个运行在 3 个不同操作系统上的服务器应用程序,我需要能够在不重新启动进程的情况下切换证书。

Another usersuggested importing multiple certificates into the same keystore. I'm not sure that helps me, though, unless there is a way to tell Java which certificate in the keystore to use.

另一位用户建议将多个证书导入同一个密钥库。不过,我不确定这对我有帮助,除非有办法告诉 Java 使用密钥库中的哪个证书。

回答by erickson

SSL can provide hints to the client about which certificate to present. This mightallow you to use one key store with multiple identities in it, but, unfortunately, most servers don't use this hinting feature. So, it will be more robust if you specify the client certificate to use on for each connection.

SSL 可以向客户端提供有关要提供哪个证书的提示。这可能允许您使用一个包含多个身份的密钥库,但不幸的是,大多数服务器不使用此提示功能。因此,如果您为每个连接指定要使用的客户端证书,它将更加健壮。

Here is sample code to set up one SSLContextwith specified identity and trust stores. You can repeat these steps to create multiple contexts, one for each client certificate you want to use. Each SSLContextwould probably use the same trust store, but a different identity store (containing the single client key entry to be used in that context).

下面是设置一个SSLContext具有指定身份和信任存储的示例代码。您可以重复这些步骤来创建多个上下文,一个用于您要使用的每个客户端证书。每个SSLContext都可能使用相同的信任存储,但使用不同的身份存储(包含要在该上下文中使用的单个客户端密钥条目)。

Initialize the contexts that you will need one time, and reuse the the correct one for each connection. If you are making multiple connections, this will allow you to take advantage of SSL sessions.

初始化您一次需要的上下文,并为每个连接重用正确的上下文。如果您建立多个连接,这将允许您利用 SSL 会话。

KeyManagerFactory kmf = 
  KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(identityStore, password);
TrustManagerFactory tmf =
  TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(trustStore);
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);

Later, you can create a socket directly:

稍后,您可以直接创建套接字:

SSLSocketFactory factory = ctx.getSocketFactory();
Socket socket = factory.createSocket(host, port);

Or, if you are using the URLclass, you can specify the SSLSocketFactoryto use when making HTTPS requests:

或者,如果您正在使用URL该类,则可以SSLSocketFactory在发出 HTTPS 请求时指定要使用的 :

HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
con.setSSLSocketFactory(ctx.getSocketFactory());

Java 6 has some additional API that makes it easier to configure sockets according to your preferences for cipher suites, etc.

Java 6 有一些额外的 API,可以根据您对密码套件等的偏好更轻松地配置套接字。

回答by Matt

There is a solution herefor dynamically choosing the client certificate used for SSL Authentication from an Axis Client.

这里有一个解决方案用于从 Axis 客户端动态选择用于 SSL 身份验证的客户端证书。