A while back I wrote a post on how to use the apache web client to connect to an SSL server without a globally recognized certificate. The easy way is just to import the certificate authority certificate into your cacerts file in $JAVA_HOME/jre/lib/security but in some cases you can’t do this, so I showed how I created a custom socket factory and then registered the socket factory with the Protocol class.
While trying to get an XHTML rendering library to work today, I had an issue with untrusted certificates that I needed to get working, but since the library wasn’t using the apache web client, I was a bit stuck. As it turns out, there is much lower level you can get to to make this work:
TrustManagerFactory tmFactory =TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());InputStream is = ClassLoader.getSystemResourceAsStream("my.truststore");trustStore.load(is, "password".toCharArray());TrustManager[] tm = tmFactory.getTrustManagers();KeyManagerFactory kmFactory =KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());KeyStore keyStore = KeyStore.getInstance("pkcs12");InputStream kis = ClassLoader.getSystemResourceAsStream("keystore.p12");keyStore.load(kis, "password".toCharArray());KeyManager[] km = kmFactory.getKeyManagers();SSLContext sc = SSLContext.getInstance("TLS");sc.init(km, tm, null);HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
I like this way a lot better because it uses classes only from the javax.net.ssl package and work perfectly for all java based network connections. All you have to do is create your keystore/truststore files and make them available to this code somewhere in the classpath.