Everything About HTTPS and SSL in Java
Click here to learn everything you need to know about HTTPS, SSL, and app security.
Join the DZone community and get the full member experience.
Join For FreeMany articles, papers, and blogs have already talked about HTTPS, SSL, and web security. Nevertheless, people still miss the basics. In this article, I tried to put all things together in the form of a questionnaire. This article will be a long read and few questions sound elementary but please bear with me as I tried to jot down, keep it simple and gripping.
"It's all about securing your systems in the world of insecure Internet."
Before even understanding HTTPS and its terminology, let's go through some of the stats and understand the usage of HTTPS. According to Google's HTTPS encryption transparency report, 80 percent of pages are loaded using HTTPS in Chrome on Windows. The web is getting more secure and more than half of the entire web traffic is encrypted now. Google started enforcing websites to adapt to HTTPS and provide SEO incentive in its search ranking.
Now, let's get into the technicality of HTTPS
What Are SSL and TLS Protocols?
Both SSL (Secure Sockets Layer) and TLS(Transport Layer Security) are cryptographic protocols that provide security over a network. They are widely used across different applications. SSL and its latest versions had a number of vulnerabilities, and hence, TLS was introduced as an updated version of SSL in the year 1999. SSL has been deprecated by the Internet Engineering Task Force (IETF) in 2015. Therefore, you should have TLS protocol enabled for your applications. You will still see a lot of SSL terminology being used across many organizations until people get accustomed to TLS.
Let's move ahead with the big question.
How Does HTTPS Work?
In layman terms, HTTPS is a secured version of HTTP. Many websites and applications are, by default, enabling HTTPS — especially if you are working on progressive web applications. HTTPS has become a norm as a part of securing your application. Every packet transferred between client and server is encrypted using public or private key cryptography.
HTTPS ensures there is at least a basic level of security involved in communication between two parties, whereas HTTP is insecure and an attacker (MiM) can breach the security.
Let us first understand a few terminologies and then connect all these dots to get a bigger picture of how HTTPS works.
Please note that I have related HTTPS with Java programming language to describe a lot of these concepts in this article.
Asymmetric Encryption
Symmetric Encryption
Asymmetric key encryption is much stronger and tougher to crack, but the downside is that the computation time is also high. Since Symmetric key is shared between clients and server for encryption and decryption, there is a high chance of security compromise. Whereas asymmetric keys don’t have this problem as the server only maintains the private key. Data is encrypted using the Public Key distributed and only who has private key can decrypt the data.
TLS Certificates
Certs are data files that have encrypted cryptographic keys with additional information such as domain name, hostname, and server details tied to an organization. If you as an organization or an entity would like to secure your application using SSL, you need to install SSL/TLS certificates onto your web server. Nowadays, Extended Validation certs are the certs that will provide the strongest security as an alternative to Standard SSL certs.
Following is the snapshot from GlobalSign, where they have nicely depicted what happens if you install EV SSL certificates, as shown in the below picture, EV SSL-enabled websites will have a padlock and a green address bar like in IE. You can also view the certs installed in the browser by clicking on the padlock on a secure website.
There are three key components used when talking about public-key certificates (typically X.509): the public key, the private key, and the certificate. The public key and the private key form a pair. You can sign and decrypt with the private key, and you can verify (a signature) and encrypt with the public key. The public key is intended to be distributed, whereas the private key is meant to be kept private.
Keystore and Truststore
Many Java developers get confused when it comes to Keystore and Truststore. In fact, few use Keystore and Truststore together and store all the certs in a single JKS, which we will discuss further. You can always do that but the recommended way is to maintain a Keystore for you to represent as a host and Truststore for sites whom you trust.
Keystore will have Private Key that identifies an organization. Typically, you will store a KeyPair (Private Key and Public Key) in a Keystore. Let's look at an example.
If you as a server wants the clients to talk to you over HTTPS, you should have Keystore setup. Whenever there is a request from a client to server, the server will present its cert from Keystore and the client will verify that certificate with the certs in its (client's) Truststore.
So what does a Keystore or a Truststore hold? I have used the Keystore Explorer tool to demonstrate a few details of HTTPS for a Java-based application. As another option, you can try using JDKs Keytool command line utility to create/manage certs or stores.
Certificate Authority
A certificate authority (CA) is an entity that issues digital certificates. A digital certificate certifies the ownership of a public key by the named subject of the certificate (Common Name or CN in a certificate). This allows others (relying parties) to rely upon signatures or on assertions made about the private key that corresponds to the certified public key. A CA acts as a trusted third party — trusted both by the subject (owner) of the certificate and by the party relying upon the certificate. The format of these certificates is specified by the X.509 standard.
In essence, the certificate authority is responsible for saying "yes, this person is who they say they are, and we, the CA, certify that."
Below is the picture of a "Chain of Trust" with a Root CA
The CA never has access to the private key. The private key remains on the server and is never shared. The public key is incorporated into the SSL certificate and shared with clients, which could be a browser, mobile device, or another server. Although the makeup of an SSL certificate consists of a private and public key, the SSL certificate itself is sometimes referred to as "the public key." The SSL certificate is also referred to as the "end entity" certificate since it sits at the bottom of the certificate chain and is not used for signing/issuing other certificates.
Now that we talked about all these concepts (TLS, Certs, Encryptions, CA, Keystore etc.), which helps in establishing a secure channel, this secure channel makes an attacker unable to read the data between client and server and you know you are talking to the server whom you intend to talk to.
What Are the Different Keystore Types?
- PKCS11 or .p11 is used less frequently for accessing hardware cryptographic tokens like network cards
- .bks are a
BouncyCastle
provider used across Android and mobile devices.
And more types like Keychain in MacOS, Windows, etc. — all of them store Private Keys, Secret Keys, and Certs.
What Are the Different File Extensions for Java Certs?
You might have gone through a lot of extensions like ".DER", ". CER", ".CRT"," .PEM." Developers get confused about when to use what.
.PEM is the container format that includes public certs or the entire certificate chains. It includes a header, body, and footer in the below fashion.
-----BEGIN CERTIFICATE REQUEST----- and -----END CERTIFICATE REQUEST----- show a CSR in PEM format.
-----BEGIN RSA PRIVATE KEY----- and -----END RSA PRIVATE KEY----- show a private key in PEM format.
-----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- show a certificate file in PEM format.
.DER is the binary or base64 format of .PEM file mostly used in windows. Windows will export certs as .DER encoded files with extensions as .CER or .CRT
.CRT is file extension for actual digital certificates.
What Is the Difference Between Self-Signed and CA?
There are two types of SSL certs when we deal with signing certificates:
Self-Signed |
CA |
Signed/issued by self | Certs signed by a trusted certifying authority |
Free to use | Paid to trust authority |
Unrecognized by browsers | Trusted by browsers and recognized |
Used when there is no sensitive information | Used in case of PII and sensitive data |
Used for Pre-Prod environments which reduces cost for local infrastructures(Intranet, Testing) |
Can be used everywhere with additional cost |
If you observe the image on the left- the "issuer" and "issued to" are same as it is a Self-signed cert signed by itself. Also, you can notice that the CA Root certificate is not trusted.
When you need multiple certificates, in a company, you might set up your own CA and install that CA's certificate in the root Keystore of all clients. Those clients will then accept all certificates signed by your CA.
This one on the left is Google's certification path, which is signed by CA-GlobalSign and an intermediate CA-G3 in the chain of trust.
If you would like to build your own Public Key Infrastructure (PKI) and issue other certificates, you need to be a CA as well.
Difference Between 1-Way and 2-Way SSL?
In general, 1-way SSL is the common way to verify the authenticity of the website you are accessing and form a secure channel. In this authentication, the client is never verified, as the content being verified is with the server.
In contrast, for 2-way SSL, both the client and server exchange certificates and verifies authenticity. Mutual trust is obtained after CA verifies both parties' certificates.
How to Configure TLS in Your Applications
Since SSL is deprecated, we shall look at configuring TLS for applications. There are many websites online where you can check whether your servers are enabled with SSL and whether they should be enabled or not. You can also view certs in browsers (like clicking on the padlock symbol in Chrome).
So, how do you configure a secure layer for your application? Does installing certificates configure TLS for your server? How are certs different from protocols?
As you know, the Transport layer also called Layer 4, which is the layer that deals with the Network stack and Host-to-Host communication (you can have a peek here). TLS/SSL does not fit into any of these layers of the OSI model but sits on top of the Transport layer. I am just trying to give a gist of where and how TLS is related to computer networking and its security.
Installing certificates is not the same as configuring TLS. It is your server that will decide which version and what protocol to use.
Configuring TLS in Apache
- Restart Apache > service apache2 restart or > service httpd restart
This will enable all protocols except SSLv2, SSLv3, TLSv1
Configuring TLS for Tomcat
- Modify the entry > sslProtocols = "TLSv1.2" for Tomcat 5&6 , > sslEnabledProtocols = "TLSv1.2" for Tomcat 7 & higher
- Restart Tomcat service.
Configuring TLS for Spring Boot
- Put the following properties into application.properties file of your Spring Boot application
#enable/diable https
server.ssl.enabled=true
#ssl ciphers
server.ssl.ciphers=TLS_RSA_WITH_AES_128_CBC_SHA256, ADD_OTHER_CIPHERS_IF_REQUIRED
# SSL protocol to use.
server.ssl.protocol=TLS
# Enabled SSL protocols.
server.ssl.enabled-protocols=TLSv1.2
- Alternativel,y you can update the Embedded Servlet Container Factory to add/remove protocols, as shown below:
@Bean
public EmbeddedServletContainerFactory servletContainerFactory()
{
TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();
factory.addConnectorCustomizers(new TomcatConnectorCustomizer() {
@Override
public void customize(Connector connector)
{
connector.setAttribute("sslProtocols", "TLSv1.2");
connector.setAttribute("sslEnabledProtocols", "TLSv1.2");
}
});
return factory;
}
Similarly, you can configure SSL for Android, Apple, and other devices, as well.
Exceptions During the SSL Handshake?
A browser can understand if a trusted certificate is installed if not add to its Truststore and then open an SSL handshake. This is pretty straight forward through a browser, but if we access a secured site using the Java client, it is a little different. It is a good practice to have your own Truststore installed at your client with the certs of the site you are trying to access to.
PKIX handshake exceptions can occur because of multiple reasons between a client and server.
javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
SSL certs are not trusted or a bad certificate is installed or a Truststore couldn't load.javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested targ
You can load a Truststore in Java using System properties, JVM arguments, or a bean on server startup and load the stores using Trust material. If any of these fail to load the Truststore or are not able to find the Truststore at all, this exception occurs.javax.net.ssl.SSLHandshakeException: no cipher suites in common
This exception can be because of TLS version mismatch or a detailed cipher negotiation(using old ciphers) at either party.- Hostname mismatch: A common name mismatch error occurs when the common name of your SSL/TLS Certificate in the Keystore of the server does not match the domain you are trying to access from the client.
There are other exceptions as well, which result in insecure connections. For local/dev environments, you can use a self-signed certificate and disable the Alias Name match for testing purposes. For example, you can control hostname verification by having a flag while creatingSSLConnectionSocketFactory
and then externalize the flag to a property file.
SSLConnectionSocketFactory socketFactory;
if(verifyHostname){
socketFactory = new SSLConnectionSocketFactory(sslContext);
}else{
socketFactory = new SSLConnectionSocketFactory(sslContext, (HostNameVerifier) (hostname, session) -> true)
}
Does Java Maintain its Own Truststore?
JDK ships with its own Truststore namedcacerts
available under $JDK_HOME/jre/lib/security/
. cacerts maintains a huge list of Root CAs from all over the world with a default password "changeit." You can alter and open it by adding ".jks" extension with a KeyToolExplorer
or list all certs using Keytool command. You have to be cautious and verify the trusted authorities for production versions of Java and remove any unused or untrusted CAs from cacerts.
A Java client if not overridden by your own Truststore will first look into JDK's default Truststore and see if a cert exists and establishes a secure connection.
Wrapping it Up!
Most of us assume that if a website uses HTTPS, it is secure. Even HTTPS is insecure and cannot fully protect your website or application unless correctly implemented. You can read this news article regarding the vulnerabilities of HTTPS. Nevertheless, every website should be secured with HTTPS to prevent the minute possibility of attacking a website.
Finally, keep your systems updated. Do check the latest versions of TLS, the validity of certs, and make sure there is no potential attack that can be traversed through your systems.
Ultimately, using HTTPS, despite its limitations, is better than leaving the web unencrypted.
Cryptography and security, for me, are like an ocean to talk about, — I just picked a tiny shell out of the ocean. I understand that there are many other aspects of HTTPS that can be discussed in greater detail. However, thanks for reading this article!
Opinions expressed by DZone contributors are their own.
Comments