My application is a web service provider running on websphere and a SOAP web service client consists of several keystores specific to each client. The app needs to be migrated to tomcat and i am struck, as i need to use a different certs to establish the TLS connection with back end server based on the incoming client request
I am using springboot and have a way to configure keystore and trustore. Followed the below link:
http://zoltanaltfatter.com/2016/04/30/soap-over-https-with-client-certificate-authentication/
I want to set the certificate/keystore at run time based on the client. To do that I am wiring Keystores and the configuration(client) names, so that I can use the client specific keystore dynamically. But this is something tightly coupled, each time i have a new client, I need to create an entry for the client and set the corresponding keystore.
But I had some another approach in mind, say I keep all certificates in one keystore , how we can access the client specific cert dynamically?
You can use a keystore to manage all your client certificates, that will be identified by an alias.
The default KeyManager
will select the first certificate in handshake, so before creating the connection no need to build your own X509KeyManager
to specify the alias to be used. See How I can tell alias of the wanted key-entry to SSLSocket before connecting?
KeyStore keystore = ... //The keystore with all your certificates
//The keymanager for an specific connection
KeyManagerFactory kmf= KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(keystore, password.toCharArray());
//Create a keyManager wrapper that returns the alias to use
final X509KeyManager origKm = (X509KeyManager)kmf.getKeyManagers()[0];
X509KeyManager km = new X509KeyManager() {
public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) {
return "alias";
}
public X509Certificate[] getCertificateChain(String alias) {
return origKm.getCertificateChain(alias);
}
// override the rest of the methods delegating to origKm ...
}
Inject the new keyManager
in HttpsUrlConnectionMessageSender
HttpsUrlConnectionMessageSender messageSender = new HttpsUrlConnectionMessageSender();
//messageSender.setKeyManagers(keyManagerFactory.getKeyManagers());
messageSender.setKeyManagers(new KeyManager[] { km });