HTTPS and Java - Pitfalls and Best Practices - Part 1

As software developers, we often want to talk to services over the internet, usually using HTTP. However, it’s now very common to see online services using HTTPS – an extension of HTTP which enables secure communications over a network.

This move has made life more interesting for developers who want to interact with these services. Most of the time, connecting to a host over HTTPS “just works” from Java, but sometimes things don’t quite work … and Java can be a bit cryptic in how it reports the failure.

To be more clear, HTTPS provides three security-related properties: Authentication, Data Integrity, and Encryption. In this post, we will look closer at two of the properties of HTTPS – Authentication and Encryption. We will also look at some of the pitfalls of HTTPS we can encounter as software developers, and how to solve them the right way.

Pitfalls

Let’s say we’re writing a Java service which calls an online service over HTTPS. How about this for an error message:

PKIX path building failed

What does that even mean? Or how about this one:

Received fatal alert: handshake_failure

It’s the worst kind of scenario: something which “ought to be simple” doesn’t work, and you don’t know why.

It might feel tempting at this point to work around the problem by disabling some validation, or falling back to plain old HTTP. But this would remove a layer of security – an irresponsible approach. So instead let’s learn all about HTTPS and Java so we can deal with these problems correctly when they occur.

But wait … why did HTTPS become so much of a thing all of a sudden?

HTTPS Everywhere

There has been a growing movement for online services to use HTTPS everywhere. For example, this talk at the Google I/O conference in 2014 gives a strong case for why “all communications should be secure by default”, not just traditionally sensitive services such as online banking.

In 2016, the Google Chrome web browser began to flag sites which collect form inputs as “Insecure” if they did not use HTTPS. Things rolled on until July 2018, when the Google Chrome web browser started to flag all websites which were not secured by HTTPS as “Not Secure”.

Example image

Nobody wants their website to look like this, so there was a strong incentive for online services to use HTTPS in an effort to not appear insecure to their users.

To enable HTTPS, a website owner would need to obtain a certificate – sometimes known in this context as a HTTPS, TLS, or SSL certificate. Remember that one of the properties of HTTPS is Authentication. In this context, authentication means the ability to prove ownership of the domain. A certificate is issued by a Certificate Authority (or CA). One responsibility of a CA is to ensure the identity of a certificate holder to ensure they are genuinely in control of the domain the certificate is issued for.

There are many Certificate Authorities available for use. One example of a fairly new Certificate Authority is Let’s Encrypt. Due to it being newly created, older versions of Java were not able to connect to hosts which used a Let’s Encrypt certificate. Java would fail to connect to the host, with the cryptic “PKIX path building failed” message which we saw earlier.

But what does this really mean? To find out, let’s learn a little more about certificates and the chain of trust.

Read on to Part 2 to continue.