I'm programming a JAX-WS client in Java. The access to the WebService is protected with a client certificate. I know the client certificate is right because I can get the WSDL in Firefox only if the client certificate was imported (in Firefox).
But I have problems to write my java application which should use the WebService. What I have do is following:
MyOwnService svc = new MyOwnService(getServerURL(), MYOWNSERVICE_QNAME);
...
...
private URL getServerURL() throws IOException {
URL url = new URL((String) cfg.get(ConfigData.SERVER_URL));
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
try {
con.setSSLSocketFactory(getFactory(new File("/etc/pki/wildfly/client.keystore"), "123456"));
} catch (Exception exc) {
throw new IOException("Client certificate error!", exc);
}
return url;
}
private SSLSocketFactory getFactory(File pKeyFile, String pKeyPassword )
throws ... {
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
KeyStore keyStore = KeyStore.getInstance("PKCS12");
InputStream keyInput = new FileInputStream(pKeyFile);
keyStore.load(keyInput, pKeyPassword.toCharArray());
keyInput.close();
keyManagerFactory.init(keyStore, pKeyPassword.toCharArray());
SSLContext context = SSLContext.getInstance("TLS");
context.init(keyManagerFactory.getKeyManagers(), null, new SecureRandom());
return context.getSocketFactory();
}
But this didn't work. If I run this I get following exception in the MyOwnService
constructor
java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty.
How is the correct way to implemnting a JAX-WS client which supports client certification?
Forget my code above. Seem's that the only thing you must do is to specify the keystore as environment variables like:
-Djavax.net.ssl.keyStore=/etc/pki/wildfly/client.keystore -Djavax.net.ssl.keyStorePassword=123456
If I do so and specifying the correct keystore it works. If I specify an invalid keystore file (which contains a other/wrong certificate/key) it don't works :) .
But I'm not sure how Java gets the right key/cert from the keystore if the keystore contains more as one PrivateKeyEntry
. Specifying javax.net.ssl.keyStoreAlias
will be have no effect. May be Java tries the PrivateKeyEntry
s until the right one was found ...
However: The only thing to do is to specify the right keystore as environment variable.