SSL certificates for Java

11 September 2022 | 3 minute read

Photo by Thomas Jensen

Introduction

Imagine writing a Java program and having to communicate with an API over HTTPS. Would it work right away? Why not? That's what we're going to find out.

Just in case, SSL stands for Secure Sockets Layer. It's what HTTPS uses to make the connection secure. Communication between a server and client is only possible if the SSL-certificate is accepted on the client side. However, sometimes it's not just the SSL certificate that brings trouble for establishing connections. Sometimes the problem starts with the network traffic itself.

We're going to troubleshoot this situation in 4 steps:

  • Step 1 and 2 are there to see whether we can actually reach the server.
  • Step 3 will allow us to retrieve the required certificates
  • Finally, step 4 guides us through the installation process of these certificates for our Java program.

1. Does the IP resolve correctly?

Check the DNS resolving IP using nslookup, dig and ping. For instance, if you're developing applications that run both on a private network as well as in the cloud, this may be necessary (for example with AWS PrivateLink, Azure Private Link or anything similar).

It may also be necessary when working on MS Windows and connecting over VPN. Why? Because of Smart Multi-Homed Name Resolution, a new feature in Windows 8/10. This feature allows faster DNS resolving by prioritizing network connections according to their speed (ethernet, wifi, vpn, ...).

In short, the DNS server from the network you're connecting with over VPN may be interfering with the address resolving from a public DNS server. The result is that the resolving IP could be different from the one needed in order for the SSL certificate to work.

1.1 nslookup

Nslookup (from name server lookup) is a network administration command-line tool for querying the Domain Name System (DNS) to obtain the mapping between domain name and IP address, or other DNS records.

$ nslookup login.microsoftonline.com
Server:		192.168.0.123
Address:	192.168.0.123#53
 
Non-authoritative answer:
login.microsoftonline.com	canonical name = ak.privatelink.msidentity.com.
ak.privatelink.msidentity.com	canonical name = www.tm.ak.prd.aadg.trafficmanager.net.
Name:	www.tm.ak.prd.aadg.trafficmanager.net
Address: 20.190.159.22
Name:	www.tm.ak.prd.aadg.trafficmanager.net
Address: 40.126.31.64
Name:	www.tm.ak.prd.aadg.trafficmanager.net
Address: 20.190.159.69
Name:	www.tm.ak.prd.aadg.trafficmanager.net
Address: 20.190.159.1
Name:	www.tm.ak.prd.aadg.trafficmanager.net
Address: 40.126.31.68
Name:	www.tm.ak.prd.aadg.trafficmanager.net
Address: 20.190.159.3
Name:	www.tm.ak.prd.aadg.trafficmanager.net
Address: 20.190.159.74
Name:	www.tm.ak.prd.aadg.trafficmanager.net
Address: 20.190.159.70

1.2 dig

dig (Domain Information Groper) is a network administration command-line tool for querying the Domain Name System (DNS). If you don't have dig on your system download BIND9 via https://www.isc.org/download/.

$ dig login.microsoftonline.com
 
; <<>> DiG 9.10.6 <<>> login.microsoftonline.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 57166
;; flags: qr rd ra; QUERY: 1, ANSWER: 10, AUTHORITY: 0, ADDITIONAL: 1
 
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;login.microsoftonline.com.	IN	A
 
;; ANSWER SECTION:
login.microsoftonline.com. 65	IN	CNAME	ak.privatelink.msidentity.com.
ak.privatelink.msidentity.com. 65 IN	CNAME	www.tm.ak.prd.aadg.trafficmanager.net.
www.tm.ak.prd.aadg.trafficmanager.net. 65 IN A	20.190.159.70
www.tm.ak.prd.aadg.trafficmanager.net. 65 IN A	20.190.159.22
www.tm.ak.prd.aadg.trafficmanager.net. 65 IN A	40.126.31.64
www.tm.ak.prd.aadg.trafficmanager.net. 65 IN A	20.190.159.69
www.tm.ak.prd.aadg.trafficmanager.net. 65 IN A	20.190.159.1
www.tm.ak.prd.aadg.trafficmanager.net. 65 IN A	40.126.31.68
www.tm.ak.prd.aadg.trafficmanager.net. 65 IN A	20.190.159.3
www.tm.ak.prd.aadg.trafficmanager.net. 65 IN A	20.190.159.74
 
;; Query time: 13 msec
;; SERVER: 192.168.0.123#53(192.168.0.123)
;; WHEN: Sun Sep 11 17:56:03 CEST 2022
;; MSG SIZE  rcvd: 276

1.3 ping

Next to nslookup and dig, there's also ping. Ping is a computer network administration software utility used to test the reachability of a host on an Internet Protocol (IP) network. It's useful in this scenario because, even when the request times out we get to see the resolving IP. So even while ICMP (Internet Control Message Protocol) may be disabled on the server, resulting in a typical Request timeout for..., we will still be able to see whether the address resolves or not. Again, this may be necessary to clarify local DNS resolving such as when working on Windows 8/10 or higher due to Smart Multi-Homed Name Resolution.

$ ping login.microsoftonline.com
PING www.tm.ak.prd.aadg.trafficmanager.net (40.126.32.139): 56 data bytes
Request timeout for icmp_seq 0
Request timeout for icmp_seq 1
Request timeout for icmp_seq 2
^C
--- www.tm.ak.prd.aadg.trafficmanager.net ping statistics ---
4 packets transmitted, 0 packets received, 100.0% packet loss

2. Is the HTTPS port accessible?

After checking whether the DNS resolving is correct and verifying that the resulting address is reachable, we have to see whether the HTTPS-port is accessible as well. We will do this using nmap and openssl

2.1 nmap

Nmap ("Network Mapper") is a free and open source utility for network discovery and security auditing. If you don't have nmap on your system, download it via https://nmap.org/download.html. We're going to check whether port 443 is accessible on the server side. This is the default HTTPS port.

$ nmap login.microsoftonline.com
Starting Nmap 7.92 ( https://nmap.org ) at 2022-09-11 18:17 CEST
Nmap scan report for login.microsoftonline.com (40.126.32.139)
Host is up (0.017s latency).
Other addresses for login.microsoftonline.com (not scanned): 20.190.160.23 40.126.32.137 40.126.32.73 40.126.32.132 40.126.32.75 40.126.32.67 20.190.160.15
Not shown: 998 filtered tcp ports (no-response)
PORT    STATE SERVICE
80/tcp  open  http
443/tcp open  https
 
Nmap done: 1 IP address (1 host up) scanned in 4.98 seconds

2.2 openssl

OpenSSL is a software library for applications that secure communications over computer networks against eavesdropping or the need to identify the party at the other end. If you don't have OpenSSL on your system download it at https://slproweb.com/products/Win32OpenSSL.html or in case you also need Git, OpenSSL is included with Git Bash at https://git-scm.com/downloads

Try to connect using openssl. We use openssl because telnet does not support TLS for connecting over HTTPS. (In other words, for unencrypted communication we could use telnet instead.)

$ openssl s_client -connect login.microsoftonline.com:443
CONNECTED(00000006)
depth=2 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root CA
verify return:1
depth=1 C = US, O = DigiCert Inc, CN = DigiCert SHA2 Secure Server CA
verify return:1
depth=0 C = US, ST = Washington, L = Redmond, O = Microsoft Corporation, CN = stamp2.login.microsoftonline.com
verify return:1
---
Certificate chain
 0 s:C = US, ST = Washington, L = Redmond, O = Microsoft Corporation, CN = stamp2.login.microsoftonline.com
   i:C = US, O = DigiCert Inc, CN = DigiCert SHA2 Secure Server CA
 1 s:C = US, O = DigiCert Inc, CN = DigiCert SHA2 Secure Server CA
   i:C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root CA
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIH0jCCBrqgAwIBAgIQA154tVXTK0FhyimmQ1t8pDANBgkqhkiG9w0BAQsFADBN
...

3. Certificates

3.1 Download the certificate

If you don't have the necessary certificates yet, you can download them from the server which you are trying to access with the following command:

$ openssl s_client -showcerts -servername {url} -connect {url}:{port} < /dev/null | openssl x509 -out {insert-certname}-x509.cert.tmp

3.2 Verify it

Make sure the certificate is valid by reading and parsing it with OpenSSL:

$ openssl x509 -in {insert-certname}-x509.cert.tmp -text

3.3 Correct it if necessary

To make sure that the file encoding and the line endings are correct, output the parsed version to a new file using OpenSSL:

$ openssl x509 -in {insert-certname}-x509.cert.tmp -out {insert-certname}-x509.cert

4. Configure Java

If you don't have Java installed on your system, you can download it at https://www.java.com/nl/download/

4.1 Add certificates to truststore

Run keytool with the -import or -importcert and the -cacerts flag in order to add the certificate to the default Java truststore.

$ keytool -import -cacerts -alias {insert-alias} -file {insert-certname}-x509.cert
 
or
 
$ keytool -importcert -cacerts -alias {insert-alias} -file {insert-certname}-x509.cert

4.2 Test connection

Next, we're going to test the connection from Java towards the server by using a simple Java program called SSLPoke. You can download it at (https://github.com/MichalHecko/SSLPoke). Test the connection with the following command. If successful, you should get the message Successfully connected.

$ java -jar SSLPoke.jar login.microsoftonline.com 443
Successfully connected

4.3 Add certificate to Microsoft Management Console

In case you're running MS Windows, you may also want to add these certificates to the Windows version for centralized certificate management. This can be done using Microsoft Management Console.

  1. Open the Run-dialog by pressing: Windows-key + R
  2. Then enter: certlm.msc
  3. Navigate to Certificates - Local Computer
  4. Open the context menu by right clicking on the folder. Click on all tasks then import.
  5. A wizard popup will show up which will allow you to add the certificate step by step.

5. Conclusion

This is it. You should now be able to connect your Java program with the required server over HTTPS.

Note: if you're still not able to connect to the required endpoint, contact your local network administrator for further debugging. It could be a firewall or network traffic routing issue.

Links

  1. https://www.isc.org/download/
  2. https://nmap.org/download.html
  3. https://slproweb.com/products/Win32OpenSSL.html
  4. https://git-scm.com/downloads
  5. https://www.java.com/nl/download/
  6. https://github.com/MichalHecko/SSLPoke