Java mutual SSL authentication / 2-way SSL authentication

Despite SSL being widely used, Java mutual SSL authentication (also referred to as 2-way SSL authentication or certificate based authentication) is a fairly simple implementation when understanding the key concepts of how mutual SSL authentication works.

Today I noticed that a relatively simple concept as this is widely misunderstood and people seem to really struggle implementing 10 lines of code.

A good primer is to first read the JSSE – Java Secure Socket Extension Reference to understand the capabilities and flexibility within Java. It is also good to understand SSLConnectionSocketFactory as we will be using it. With that in mind, you will then also understand the following concepts required to make mutual authentication work:

 

The Truststore

The Truststore contains the certificates you use to authenticate / trust other servers. Every Java install comes with it’s own truststore located in $JAVA_HOME/lib/security/cacerts. In our case we will create our own Truststore which will then store trusted CA (Certificate Authority) entries and/or self-signed certificates from third parties we trust.

The Identitystore

The Identitystore is a secure store for keys used in the SSL protocol. We use the Identitystore to store our private keys and their associated certificates used to authenticate ourselves as the client to a server. In mutual SSL authentication we (our Java client) needs to authenticate with the server.

The Java keytool

Java provides the command-line tool “keytool” which we will use in conjunction with openssl to create the above keystores and/or convert certificates.

A note about security: In the example and scripts below we will use hard-coded, simple passwords and key files without passwords. In a production environment you will typically sandbox the key generation and would access passwords from configuration stores and not hardcode in code.

Use Curl to check your certs

When you integrate mutual SSL authentication with a third party, you will typically generate a CSR (Certificate Signing Request) with your private key. The third party will then issue you with a client certificate (and typically will often provide you with CA certificate). Before we dive into the coding part, let’s use good old curl to validate the request

The above request uses a JSON HTTP post against a 3rd-party end-point using our client-certificate and client key. If this request succeeds without an error or SSL-handshake issue, we can almost start to code.

Note: Replace the variable $CERT_ALIAS with the actual certificate alias. Use your own password in place of $CERT_PASSWORD.

Generate the TrustStore

If your 3rd party does not provide you with their server certificate, you can easily retrieve it via openssl (otherwise skip the first step):

Generate the IdentityStore

In the IdentityStore will put our private key, our certificate and the CA chain under an alias which our client is going to use to authenticate itself with the server:

 

Let’s code

The code itself is pretty simple and requires not much explanation. We load the identitystore and truststore into a custom SSL context, create a SSLConnectionSocketFactory and then bind it to a HttpClient.

 

If the above has saved you from trawling through endless Stackoverflow posts for days and you have failed hacking away at code without much success, why don’t you throw some money at the screen:

🍺 Pay it forward: If any of my content helped you in any way, then follow me on Twitter or send me some coins:

Affiliates: Binance (#altcoins), Coinbase (buy/sell ETH/BTC, get 10$), CoinTracking.info (get 10% off), TradingView (trend reports) or old-school PayPal.

 

 

Print Friendly, PDF & Email