My application has a private keystore that contains trusted, self-signed certificates for use on a local network - say mykeystore.jks . I want to be able to connect to public sites (e.g. google.com), as well as to my local networks, using the self-signed certificates that were provided locally.
The problem is that when I connect to https://google.com , path creation fails because installing my own keystore overrides the default keystore containing the root CAs bundled with the JRE, reporting an exception
sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
However, if I import the CA certificate into my keystore ( mykeystore.jks ), it works fine. Is there a way to support both?
I have my own TrustManger for this purpose,
public class CustomX509TrustManager implements X509TrustManager { X509TrustManager defaultTrustManager; public MyX509TrustManager(KeyStore keystore) { TrustManagerFactory trustMgrFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); trustMgrFactory.init(keystore); TrustManager trustManagers[] = trustMgrFactory.getTrustManagers(); for (int i = 0; i < trustManagers.length; i++) { if (trustManagers[i] instanceof X509TrustManager) { defaultTrustManager = (X509TrustManager) trustManagers[i]; return; } } public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { try { defaultTrustManager.checkServerTrusted(chain, authType); } catch (CertificateException ce) { } } }
Then I initialize SSLContext, TrustManager [] trustManagers = new TrustManager [] {new CustomX509TrustManager (key store)}; SSLContext customSSLContext = SSLContext.getInstance ("TLS"); customSSLContext.init (null, trustManagers, null);
and install the factory socket,
HttpsURLConnection.setDefaultSSLSocketFactory(customSSLContext.getSocketFactory());
Main program
URL targetServer = new URL(url); HttpsURLConnection conn = (HttpsURLConnection) targetServer.openConnection();
If I donβt install my own trustees, it communicates perfectly with https://google.com . How to get a "default trust manager" that points to the default keystore?
java ssl x509 jsse
varrunr Apr 17 '14 at 22:13 2014-04-17 22:13
source share