I just wrote a small post on how to setup Jetty to support client-side certificates (http://www.smartjava.org/content/embedded-jetty-client-certificates). To easily test the configuration I use the latest HTTPClient from from http://hc.apache.org/httpcomponents-client-ga/. This is a great client, but, once again, the documentation on how to configure this client for two-way ssl isn’t that easy to be found. The following piece of java code uses HTTPClient to make a GET call using client-side certificates. In this example I haven’t defined a specific truststore for this client, since the server certificate is already trusted by my cacerts file.
// read in the keystore from the filesystem, this should contain a single keypair KeyStore clientKeyStore = KeyStore.getInstance("JKS"); clientKeyStore.load(new FileInputStream(KEYSTORE_LOCATION), KEYSTORE_PASS.toCharArray()); // set up the socketfactory, to use our keystore for client authentication. SSLSocketFactory socketFactory = new SSLSocketFactory( SSLSocketFactory.TLS, clientKeyStore, KEYSTORE_PASS, null, null, null, (X509HostnameVerifier) SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); // create and configure scheme registry SchemeRegistry registry = new SchemeRegistry(); registry.register(new Scheme("https", 443, socketFactory)); // create a client connection manager to use in creating httpclients ThreadSafeClientConnManager mgr = new ThreadSafeClientConnManager(registry); // create the client based on the manager, and use it to make the call httpClient = new DefaultHttpClient(mgr); // create the method to execute HttpGet m = new HttpGet(path); // execute the method HttpResponse response = httpClient.execute(m);
A note on this section:
This tells the SSLSocketFactory to accept the certificate even if the hostname doesn’t match the information from the certificate. Especially useful when testing using self-signed certificates or changing ip-addresses. Note that you shouldn’t, of course, use this in production.