在我的Java应用程序中,我需要使用SSL连接到同一主机,但是每次都使用不同的证书。我需要使用其他证书的原因是,远程站点使用嵌入在证书中的用户ID属性来标识客户端。
这是一个在3个不同的操作系统上运行的服务器应用程序,我需要能够在不重新启动进程的情况下切换证书。
另一位用户建议将多个证书导入同一密钥库。不过,我不确定是否可以帮到我,除非有一种方法可以告诉Java使用密钥库中的哪个证书。
SSL可以向客户端提供提示,提示要显示的证书。这可能允许你使用一个具有多个身份的密钥存储,但是,不幸的是,大多数服务器不使用此提示功能。因此,如果你指定要用于每个连接的客户端证书,它将更加健壮。
这是SSLContext
使用指定的身份和信任库建立示例代码的示例。你可以重复这些步骤来创建多个上下文,每个要使用的客户端证书都需要一个上下文。每个人SSLContext
都可能使用相同的信任库,但使用不同的身份库(包含要在该上下文中使用的单个客户端密钥条目)。
初始化一次所需的上下文,然后为每个连接重复使用正确的上下文。如果要建立多个连接,这将使你能够利用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);
稍后,你可以直接创建套接字:
SSLSocketFactory factory = ctx.getSocketFactory();
Socket socket = factory.createSocket(host, port);
或者,如果你使用的是URL
类,则可以指定SSLSocketFactory
在发出HTTPS请求时要使用的:
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
con.setSSLSocketFactory(ctx.getSocketFactory());
Java 6有一些附加的API,可以更轻松地根据你对密码套件等的偏好配置套接字。
“ Java 6有一些附加的API,可以更轻松地根据您对密码套件的偏好配置套接字”。您能否指出我关于这些配置的更多文档/讨论?
@ Tazzy531-添加了Java 6
SSLParameters
,您可以通过一次操作将其设置为一个SSLEngine
或一个SSLSocket
。@erickson,能否请您举例说明哪个服务器使用此提示功能?还是自09年以来,大多数服务器不使用此功能,它已发生变化?