Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using multiple SSL client certificates in Java with the same host

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.

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.

Another user suggested 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.

like image 976
cwick Avatar asked May 20 '09 18:05

cwick


People also ask

Can you have 2 SSL certificates on one server?

A lot of people want to know whether you can install multiple SSL certificates on a single domain. The answer is yes.

Can a truststore have multiple certificates?

You can have a keystore with as many certificates and keys as you like. If there are multiple certificates in a keystore a client uses as its truststore, all certificates are being looked at until one is found that fits. You can look at the preinstalled certificates, they are in /lib/security/cacerts.

Do I need multiple SSL certificates?

In most cases, you'll only need one SSL certificate for your domain. But in certain cases, you might need two certificates for a single domain.

Can you have two wildcard certificates for the same domain?

Yes, you can use two different certificate for the same common name.


1 Answers

SSL can provide hints to the client about which certificate to present. This might allow 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.

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

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.

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 URL class, you can specify the SSLSocketFactory to use when making HTTPS requests:

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.

like image 98
erickson Avatar answered Sep 20 '22 13:09

erickson