| Article Index |
|---|
| 1. Java and HTTP / HTTPS |
| 2. The Problem |
| 3. The Solution |
| 3.1. Sample Java Code |
| 3.2. Prepare a Key Store |
| 3.3. JVM Parameters |
| 3.4. Starting the JVM |
You are utilizing Java 5 or Java 6 and you want to establish a network connection to a HTTPS server? This task can be tricky if the server side is using a certificate issued by an certificate authority (CA) that is unknown to your Java Virtual Machine (JVM).
This article shows you how to encourage your JVM to talk to server backend systems with custom SSL certificates.
1. Java and HTTP / HTTPS
Java supports to establish connections to servers by talking HTTP and HTTPS by defaut. However, the JVM has registered a set of CAs that are trustworthy. Connections the servers containing certificates signed from CAs that are unknown to your JVM are rejected by throwing a SSLHandshakeException and a SunCertPathBuilderException. You will get error messages like 'PKIX path building failed' and 'unable to find valid certification path to requested target'.
2. The Problem
Java is intended to be a secure environment for applications running in virtual machines. So not anyone is allowed to provide data to your applications by default. There are an number of opportunities to get around this problem. This article will show you an example to end up successfully with this task.
3. The Solution
As usual there are a number of solutions to reach your aims. Here are a number of possible approaches.
- Extend the default keystore with custom certificates. This step might be difficult if you do not have administrative access permissions at the machines that are running your programs.
- Extend your program to ignore all certificate failures.
- Customize your program and utilize a newly created key store.
- Setup a security manager with a custom rule set.
- ...
- Create a key store and tell your JVM to utilize it at start time.
From all these approaches the latter one is the solution that we will try to configure in this article!
3.1. Sample Java Code
This is a code example to open a HTTP(s) connection. Without any additional code or configurations this application will fail, when connection to an unsecure server.
1 |
import java.io.BufferedReader; |
This is a very simple connection tester. If available, it takes the first command line argument and tries to connect to this url. If no parameter is available a default server will be utilized (www.linux-support.com via HTTPS). The method doit(...) is opening the network connection and is printing out all the data that has been received. If an error occures (like there is an untrusted server at the other end of the network connection) an exception will be thrown.
3.2. Prepare a Key Store
Now we want to create a key store to be provided to your JVM. It may contain any number of certificates. In this example we will add the certificate of the CA, that did sign the certificate of our target HTTPS server. This will result in successful network connections for all requests to servers this CA did sign. So we do not need to import all the certificates of each and every HTTPS service we want to talk to.
# create a key store and import the certificate of a CA
$ keytool -import -storepass passwd -keystore mykeystore -alias lsca -file cacert.crt
This single line is performing all the following steps at once:
- create a key store named mykeystore
- set the password passwd for the keystore (it is required to secure and access data within the key store)
- import the certificate cacert.crt into the key store
- set the alias lsca for the imported certificate
If you are asking yourself, where to get the CA certificate from, we have got a reassuring answer to you. Each CA is publishing its certificate at its public website. If you are interested in connecting to the preconfigured default Url (see above) you may download the CA certificate at the following location: http://www.linux-support.com/cert/cacert-premium.crt
3.3. JVM Parameters
These are the parameters recognized by the JVM to start with an additional key store and/or trust store.
-Djavax.net.ssl.keyStoreType=pkcs12
-Djavax.net.ssl.trustStoreType=jks
-Djavax.net.ssl.keyStore=clientcertificate.p12
-Djavax.net.ssl.trustStore=gridserver.keystore
-Djavax.net.debug=ssl # very verbose debug
-Djavax.net.ssl.keyStorePassword=$PASS
-Djavax.net.ssl.trustStorePassword=$PASS
Don't worry. For our example we just need two parameters from that list.
3.4. Starting the JVM
Now we are ready to start the application. After compiling the sample application and creating the key store you might key-in the following command line to connect to the preconfigured default url. In the next example we assume that your application is packaged within the file test-https.jar.
# run the application
$ java -Djavax.net.ssl.keyStorePassword=passwd \
-Djavax.net.ssl.trustStore=mykeystore \
-jar test-https.jar
# run the application from an intranet by utilizing
# a proxy server
$ java -Djavax.net.ssl.keyStorePassword=passwd \
-Djavax.net.ssl.trustStore=mykeystore \
-Dhttp.proxyHost=wwwproxy.yournet.corp \
-Dhttp.proxyPort=8080 \
-Dhttps.proxyHost=wwwproxy.yournet.corp \
-Dhttps.proxyPort=8080 \
-jar test-https.jar
Have a lot of fun with your new extended SSL client!
Related articles:




