DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • Securing AI/ML Workloads in the Cloud: Integrating DevSecOps with MLOps
  • Five Nonprofit & Charity APIs That Make Due Diligence Way Less Painful for Developers
  • API Analytics: Unleashing the Power of Data-Driven Insights for Enhanced API Management
  • What’s the Future of Device Management? 5 Predictions For What Lies Ahead

Trending

  • Compliance Automated Standard Solution (COMPASS), Part 11: Compliance as Code, the OSCAL MCP Server Way
  • The Agentic Agile Office: Streamlining Enterprise Agile With Autonomous AI Agents
  • A Walk-Through of the DZone Article Editor
  • Using LLMs to Automate Data Cleaning and Transformation Pipelines
  1. DZone
  2. Software Design and Architecture
  3. Security
  4. Apache HTTP Client:  Client-Side SSL Certificate

Apache HTTP Client:  Client-Side SSL Certificate

Need help working with your Apache HTTP Client?

By 
Simone Pezzano user avatar
Simone Pezzano
·
Mar. 25, 19 · Tutorial
Likes (5)
Comment
Save
Tweet
Share
52.2K Views

Join the DZone community and get the full member experience.

Join For Free

I’m sharing this snippet with you because it’s been a little tricky to work with, so I hope that I can save you some time.

Note: I’m referring to Apache HTTP Client 4.3. You know its API is pretty lively, so before you dive into it, make sure it applies to the version you’re using as well.

Background

Creating an HTTP connection using Apache HTTP Client is pretty straight forward, and this is why we love it. Fine tuning how the client works is essential in production environments, and it does require a little bit of tweaking, but the results are excellent.

It’s not a surprise that client-side SSL certificates (also known as two-way SSL or mutual SSL authentication) is doable, but of course, being something that interferes with the intimate nature of the HTTP conversation, the process isn’t exactly straight forward.

If you’re unaware of this security practice, here’s the shortest possible summary: to provide stricter security for HTTPS connections involving very selected parties, you can let them have an SSL client certificate that will identify them. The SSL dance will not work if the server and client certificates are not a match. By doing so, no credential is sent over the Internet, just encrypted data that will be decrypted correctly only if the certificates match.

If you want to know more, here’s a useful article by Robin Howlett.

Practice

Incomplete chains, root certificates that need to be updated, etc. — certificates are a pain already. So, you would assume that this is a piece of cake, right?

First off, let’s be clear about the fact that you are not going to configure this for a specific connection. The HTTP Client instance needs to be built around the fact that it will support that certificate.

First, let’s create a keystore:

KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());


The factory will create a JKS keystore by default. You can alter which one you will get by changing the parameter. For example, PKCS12 is an option. I’m sticking with JKS for this example. This implies that you already created a keystore and added the certificate to it.

Secondly, we load the keystore:

ks.load(inputStream,"password")


Any inputStream will do. We need to provide a password to decode the keystore, of course.

SSLContext sslContext = SSLContexts.custom()
                                .loadKeyMaterial(ks, "password".toCharArray())
                                .loadTrustMaterial(null, new TrustSelfSignedStrategy())
                                .build();


We basically create a custom SSL Context, load the keystore, and load the trust store (the null parameter will default to the cacerts file).

SSLConnectionSocketFactory sslConnectionFactory =
                                new SSLConnectionSocketFactory(sslContext, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);


We create a socket connection factory providing the SSL context. The hostname verifier is literally up to you, and it pretty much depends on the service you will be interactive with. The  ALLOW_ALL_HOSTNAME_VERIFIER is loose, so you might want to consider moving it to “strict” if the server allows you to.

Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
                                                        .register("https", sslConnectionFactory)
                                                        .register("http", new PlainConnectionSocketFactory())
                                                        .build();


This registry associates what socket factory to use based on the protocol.

BasicHttpClientConnectionManager connManager = BasicHttpClientConnectionManager(registry);


We instantiate a connection manager that will use the registry. We’re using the basic connection manager here because it’s simpler for the example. Connection managers are a vital part of tuning HTTP client, so make sure you’re using something that suits your use case.

HttpClient client = HttpClients.custom()
                                .setConnectionManager(connManager)
                                .setSSLSocketFactory(sslConnectionFactory)
                          .setHostnameVerifier(SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER)
                          .build();


We finally instantiate our HTTP client that will eventually be successful when talking to our highly secure peer. As we mentioned previously, the hostname verifier has to be edited based on your needs.
Note: this example contains only the strictly necessary commands to make it work. A lot of other configuration options may be needed in your context.

And we should be set to go.

Let me repeat one important point: before you dive into this practice, make sure it suits your HTTP Client version. Various refactoring and changes in the API may strongly impact the way to do it.

Hope this helps! Take care.

Connection (dance) Factory (object-oriented programming) IT security API Snippet (programming) Trust (business) Data (computing) Production (computer science)

Published at DZone with permission of Simone Pezzano. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Securing AI/ML Workloads in the Cloud: Integrating DevSecOps with MLOps
  • Five Nonprofit & Charity APIs That Make Due Diligence Way Less Painful for Developers
  • API Analytics: Unleashing the Power of Data-Driven Insights for Enhanced API Management
  • What’s the Future of Device Management? 5 Predictions For What Lies Ahead

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook