users@jersey.java.net

[Jersey] Performance issue using Jersey Client with SSL

From: Chirag Dewan <chirag.dewan_at_ericsson.com>
Date: Wed, 17 Jun 2015 07:01:19 +0000

Hi All,

I have a jersey client which consumes requests over HTTPS. My Client code is as follows(Sorry for the poor formatting):

ClientConfig config = new DefaultClientConfig();

                                if(!protocol.equalsIgnoreCase("HTTPS"))
                                {
                                                String trustStorePath = getValueFromKey(KEY_STORE_PATH_KEY, arguments);
                                                String trustStorePassword = getValueFromKey(KEY_STORE_PASSWORD_KEY, arguments);

                                                config.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES, new HTTPSProperties(null,buildSSLContext(null, null, trustStorePath, trustStorePassword)));
                                }
                                // async thread pool for jersey client
                                config.getProperties().put(ClientConfig.PROPERTY_THREADPOOL_SIZE, threadPoolSize);
                                client = Client.create(config);
                                resource = client.resource(url);

                                resource.type("application/json").post(ClientResponse.class);


private SSLContext buildSSLContext(String keyStorePath, String keyStorePassword, String trustStorePath, String trustStorePassword)
                                                throws Exception
                {

                                TrustManager trustManagers[] = null;
                                KeyManager keyManagers[] = null;

                                if(null != trustStorePath && !"".equalsIgnoreCase(trustStorePath))
                                {
                                                trustManagers = new TrustManager[] {new MyX509TrustManager(trustStorePath, trustStorePassword.toCharArray())};
                                }

                                if(null != keyStorePath && !"".equalsIgnoreCase(keyStorePath))
                                {
                                                keyManagers = new KeyManager[] {new MyX509KeyManager(keyStorePath, keyStorePassword.toCharArray())};
                                }

                                SSLContext context = SSLContext.getInstance("TLS");
                                context.init(keyManagers, trustManagers, null);

                                return context;

                }

static class MyX509TrustManager implements X509TrustManager
                {

                                /*
                                * The default PKIX X509TrustManager9. We'll delegate decisions to it, and fall back to the logic in this class if the default
                                * X509TrustManager doesn't trust it.
                                */
                                X509TrustManager pkixTrustManager;

                                MyX509TrustManager(String trustStore, char[] password) throws Exception
                                {
                                                this(new File(trustStore), password);
                                }

                                MyX509TrustManager(File trustStore, char[] password) throws Exception
                                {
                                                // create a "default" JSSE X509TrustManager.

                                                KeyStore ks = KeyStore.getInstance("JKS");

                                                ks.load(new FileInputStream(trustStore), password);

                                                TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX");
                                                tmf.init(ks);

                                                TrustManager tms[] = tmf.getTrustManagers();

                                                /*
                                                * Iterate over the returned trustmanagers, look for an instance of X509TrustManager. If found, use that as our "default" trust
                                                * manager.
                                                */
                                                for(int i = 0; i < tms.length; i++)
                                                {
                                                                if(tms[i] instanceof X509TrustManager)
                                                                {
                                                                                pkixTrustManager = (X509TrustManager) tms[i];
                                                                                return;
                                                                }
                                                }

                                                /*
                                                * Find some other way to initialize, or else we have to fail the constructor.
                                                */
                                                throw new Exception("Couldn't initialize");
                                }

                                /*
                                * Delegate to the default trust manager.
                                */
                                public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException
                                {

                                                pkixTrustManager.checkClientTrusted(chain, authType);

                                }

                                /*
                                * Delegate to the default trust manager.
                                */
                                public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException
                                {

                                                pkixTrustManager.checkServerTrusted(chain, authType);

                                }

                                /*
                                * Merely pass this through.
                                */
                                public X509Certificate[] getAcceptedIssuers()
                                {
                                                return pkixTrustManager.getAcceptedIssuers();
                                }
                }



The difference in TPS(trans per sec) between HTTP and HTTPS is ~10x. I don't understand why?

I am not sure if HTTPSURLConnection class is not keeping keep-alive somehow and creating a new connection for every request(means SSL handshaking per request). Could this be the reason? Is my certificate implementation blocking the request or taking more time to resolve the cryptographic keys somehow?

Any help would be greatly appreciated.

Thanks,

Chirag