Wednesday, October 2, 2019

SSL HTTP Client : Java HTTP Client Using Bouncy Castle Security Provider

Hi,

In this blog I am going to share my experience about the problem during the development I encountered.

While I was developing the other requirements, a high priority requirement came which pushed all others aside and made me to work on it.

The requirement was very simple, I have to contact or connect to a server to push a message, so that the server would store the message and push to a appropriate participant of the system.

Sounds simple right!!!

Even I thought the same, having the developers pride on top of my head, started writing java classes saying to myself I could finish this by end of the day.

Unfortunately I could not make up by end of the day, I was running the java classes written to contact the server but it failed every time saying the following error...

error: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure

Then I started digging in what was causing the problem.... the first problem I realised was, I knew nothing about the server that I am communicating with and I had few questions though which has to be answered to move forward...

What is the security mechanism in place?

What the server expects from the request?

During the research, We found that the server is at security level TLS 1.2 and the Client which communicates with the server should send the request that compliance to TLS 1.2

One other thing and important one is that the Java installed on the development environment, I was using 1.7.0 and update 79, this java isn't fit to make up a client to generate the request in compatible with the security policies that the server has  and is the case with java-1.7.0_80

Java-1.7.0_80 is the last free update from oracle and the updates above this are paid ones.

I was in a situation where I cannot make the java upgrade over 1.7.9_80 because I had the same development environment as that of the production with respect to java, moreover the security providers that comes along with java till 1.7.0_80 is not capable enough to make TLS compatible client to communicate with the server.

Having said all these, we started to search for the custom security provides in place of the default ones provided by java, the search ended in bouncy-castle

then good things started to happening....

Enough of the story I went through, lets get into the technical aspect of hunting the problem...

Prerequisites
Name Version Download Page Direct Link
Java 1.7.0_79 N/A N/A
Apache Maven 3.6.0 N/A N/A
GIT 2.7.4 N/A N/A

From the prerequisite section please download the softwares and have it installed in your system, I am not going to discuss the installation procedures of the same because we have plenty of online resources to have it done.

For you guys to test and make up your own client, I have made a simple application, I mean very very simple to show case the communication between the client and the server...

Below is the location of the project, use git package to clone
> git clone https://github.com/ravaneswaran/bouncy-castle-ssl-http-client-demo.git

To download the same as ZIP package, use the following url

Move to the directory where you have cloned or unzipped the downloaded package to test the client using the following commands.

Please change the END_POINT in the file "demo.rc.http.client.TLSHttpClient" before you compile and run the code...

> mvn clean compile
> mvn exec:java -Dexec.mainClass="demo.rc.http.client.TLSHttpClient"

Well this has solved my problem, hope it does the same for you too...

Hope you enjoyed it... thanks.

1 comment:

  1. Hi Ravaneswaran,
    Thanks for the article and the shared code. it really helped but I am facing another issue in this. can you please assist.
    org.bouncycastle.crypto.tls.TlsFatalAlert: certificate_unknown(46)
    at org.bouncycastle.crypto.tls.TlsUtils.validateKeyUsage(Unknown Source)
    at org.bouncycastle.crypto.tls.TlsECDHKeyExchange.processServerCertificate(Unknown Source)
    at org.bouncycastle.crypto.tls.TlsClientProtocol.handleHandshakeMessage(Unknown Source)
    at org.bouncycastle.crypto.tls.TlsProtocol.processHandshakeQueue(Unknown Source)
    at org.bouncycastle.crypto.tls.TlsProtocol.processRecord(Unknown Source)
    at org.bouncycastle.crypto.tls.RecordStream.readRecord(Unknown Source)
    at org.bouncycastle.crypto.tls.TlsProtocol.safeReadRecord(Unknown Source)
    at org.bouncycastle.crypto.tls.TlsProtocol.blockForHandshake(Unknown Source)

    ReplyDelete

How to change the root password in linux when it is forgotten/to change

This blog is all about changing the root password of the Linux system when it is forgotten or to reset the password...   Let's get it ...