Use Signed SSL Certificate with Java

It seems to me like every time I have to do something that has to do with SSL certificates – be they self-signed or signed by a certificate authority – things do not go smoothly. I only do this from time to time, so I am by no means an expert; but I do believe my difficulties result to some degree from the intrinsic complexities within SSL and the systems which support it.

I have created another guide which walks step by step through the process of configuring a Java key store with a signed SSL certificate. If you do want this to succeed, note that you have to follow every step precisely. Even minor omissions can lead to errors (believe me, I’ve tried it myself).

  • Download Portecle (from here) and Unzip it
  • Start portecle.jar by double clicking it
  • Go to File / New Keystore

  • Select JKS and click [OK]
  • Go to Tools / Generate Key Pair

  • Select Algorithm RSA and Key size 2048
  • Increase validity from the default 356 to 1000 or more days

  • In Common Name provide the domain or subdomain of the domain you want to protect
  • Provide some input for all other fields – do not leave any empty
  • Provide a password and remember it (This can be the same password as for the the whole store)
  • Provide an alias – best the name of your domain

  • You should see the following:

  • Right click the key pair you have create and select ‘Generate Certification Request’

  • Portecle will generate file ‘XYZ.csr‘ for you.
  • Provide the contents of this file to the SSL provider of your choice (see a brief comparison here – I’ve had good experiences with RapidSSL certificates from GoGetSSL).
  • Your SSL provider should supply you with an SSL certificate. This file should end with ‘.crt‘. Download it.
  • Go back to Portecle and right click your key pair again. Select ‘Import CA Reply’.

  • Import the .crt file you got from your SSL provider.
  • If this does not work, first proceed to import the certificates as listed in the next steps, then try again to import the CA Reply.
  • You can import the ROOT certificate of your SSL provider just in case.
  • Also, your SSL provider will supply you with an intermediate and server certificate. You can import these into your keystore as well.
  • Note that when importing the ROOT certificate of your provider, you might get a warning that no trust chain can be established to the certificate. However, when importing the intermediate and server certificates AFTER importing the root certificate, there should be no warning that no chain can be established.
  • Your keystore should look something like this now:

  • Now go to File / Save Keystore
  • Provide the same password you used before.

Now you can use the created key store in Java servers. For an easy way how to use a keystore with Java, check out step 7 in this post.

Using RapidSSL Certificate from GoGetSSL for Java Server

IMPORTANT: I found it a lot easier and less error prone to use the GUI tool Portecle to go about generating a SSL certificate/key. You can find my instructions to do so in another post.

The following steps show how a RapidSSL certificate obtained through GoGetSSL can be used to secure a Java server.

Step 1: Purchase Certificate

Go to gogetssl and purchase a Standard RapidSSL certificate (should be around $5 / year).

Step 2: Create Keystore

Run:

keytool -keysize 2048 -genkey -alias tomcat -keyalg RSA -keystore server.keystore

When asked for ‘What is your first and last name?’ enter the domain of your server (can also be a subdomain).

Press ENTER when prompted for ‘Enter key password for <tomcat>’

Step 3: Create CSR 

Run:

keytool -certreq -keyalg RSA -alias tomcat -file server.csr -keystore server.keystore

Open the file server.csr and copy its contents into the clipboard.

Step 4: Upload CSR to GoGetSSL

Login to GoGetSSL and select ‘Manage SSL Certificates’ / All.

Next to the certificate you have just purchased should be a [Generate] button. Click it.

Choose ‘Order Type’: ‘New Order’

Choose ‘Web Server Software’: ‘Jakart-Tomcat’

Paste the CSR you copied from server.csr.

Choose signature algorithm SHA2.

Click [Validate CSR]

Step 5: Perform Email Validation and Give Your Details

Specify an email address to which the validation email should be sent and click [Next Step].

Also give your details and confirm the RapidSSL terms and conditions.

Note: Now wait a few minutes until you get the email and confirm it when you got it.

Step 6: Import RapidSSL Certificates Into Keystore

You will receive an email with the certificate for the server and the intermediate certificate from RapidSSL.

You’ll need to add both to your keystore.

First the intermediate certificate:

Get it from the email and paste it into a file ‘intermediate.crt’ and put it into the same folder as you keystore. Then run:

keytool -import -trustcacerts -alias intermediate -file intermediate.crt -keystore server.keystore

You should get a message ‘Certificate was added to keystore’

Then the server certificate:

Get it from the email and paste it into a file ‘server.crt’ and put it into the same folder as you keystore. Then run:

keytool -import -trustcacerts -alias server -file server.crt -keystore server.keystore

You should again get a message ‘Certificate was added to keystore’.

Now you can use server.keystore to secure your Java Webserver with SSL.

MySQL ERROR 2026 (HY000): SSL connection error – Some Troubleshooting Ideas

I just spent a fair amount of time setting up MySQL replication between two servers encrypted by SSL (using MySQL 5.1.73).

I struggled with fixing a nasty error displayed only as ‘ERROR 2026 (HY000): SSL connection error‘.

In the following, I have collected a few possible strategies for resolving this error:

  • Is the password for the user on your server shorter than 36 characters?
  • Do the *.pem files on the server and client have the right file permissions?
  • Do your client and server certificates use a different COMMON NAME?
  • Have you tried a basic SSL setup with only certificate authority certificate (e.g. ca-cert.pem), server certificate (e.g. server-cert.pem) and server key (e.g. server-key.pem) (see). In theory, client certificates are not required for a basic setup.
  • Have you tested your certificates with a simple openssl HTTP server (see)?
  • Is your private key in the PKCS#1 format (file starts with ‘—–BEGIN RSA PRIVATE KEY—–‘)? (see, see)
  • Did you generate your certificates with TinyCA with the default settings?
  • Did you try connecting to the server WITHOUT using the certificate authority certificate (e.g. ca-cert.pem) BUT WITH specifying a client certificate and key?
    • mysql –ssl –ssl-cert=[client_cert] –ssl-key=[client_key] -u[ssluser] -h[server] -p[ssluser psw]
  • Is your certificate ‘simple enough’ for the MySQL SSL implementation e.g. not a chained certificate tree? (see) Or did you use a wildcard certificate (which are not supported) (see).

Good luck 🙂

Resources

SSL Certificate Comparison

With recent developments brining Internet security into the spotlight (such as heartbeat), SSL certificates are easily one of the cornerstones of any Internet-enabled application.

Unfortunately, a simple Google search does not easily reveal the best options for obtaining SSL certificates. Thus, I have compiled a small list of popular SSL certificate providers.

Free

StartSSL seems to be the way to go to get a free SSL certificate. Their desktop browser support seems reasonable but there might be problems with some mobile browsers and applications.

Low Price < US$10

Low price SSL certificates (for domain validation) can be obtained from resellers. GOGETSSL and namecheap seem to be good options. In my understanding, these issue essentially identical certificates to those obtained directly through RapidSSL or Comodo.

Medium Price < US$100

Further popular providers for SSL certificates are GoDaddy, RapidSSL and Comodo. All of these offer solid certificates trusted by most browsers and platforms (though, at present, GoDaddy certificates are not supported in the latest JDKs).

This list is specifically about the most basic form of SSL certificates, which only validate your domain and not your business name. However, I think for most applications these are more than enough. While for domain-only verification I would recommend the low-price options listed above, for business name verification I would recommend going directly to a more established provider.

 

Speed Up Netty SSL

Knowing Where You Are

First you can do a few simple test to see how good (or bad) your current SSL configuration of your Netty server is. Note: These tools also work with any other web server.

  • Perform the wormly SSL Web server test on your server to get an idea how well your server is configured.
  • For a more comprehensive test, consider to use the tool sslyze, which will test your server SSL configuration.

Just download their executable from https://github.com/nabla-c0d3/sslyze/releases, unpack the repository and run

sslyze.exe –regular yourserver.com

The test might run for a while but will generate a very informative report.

Improving Netty Performance

Depending on your results in the first step, you might consider the following ways to improve the performance of your Netty server:

  • Assure to keep HTTP connections ALIVE.

This requires to send a ‘Content-Length’ header to the browser and not to close the channel after a response has been written to the channel.

References

Stackoverflow – Slow Java SSL in a netty application

5 easy tips to accelerate SSL

Setting Up SSL with Netty

SSL is unquestionably a very useful and powerful technology to make systems more secure. Java in general and Netty in specific provide strong out-of-box support for supporting SSL encryption and authentication. However, since SSL is a complex technology it can often be cumbersome and difficult to set it up correctly.

The following steps describe how an SSL certificate can be obtained and configured to be used in Netty.

Step 1: Create a Keystore

Create a keystore using Java’s keytool (it’s in the [path to java]/bin directory if it’s not on your classpath):

keytool -keysize 2048 -genkey -alias tomcat -keyalg RSA -keystore tomcat.keystore

Step 2: Create a Certificate Signing Request (CSR)

You need to generate this request to submit it to whichever party you would like to issue your SSL certificate (e.g GoDaddy or StartSSL). Again, use Java’s keytool:

keytool -certreq -keyalg RSA -alias tomcat -file yourdomain.csr -keystore tomcat.keystore

Step 3: Upload Certificate Singing Request to Issuer

Go to your issuer’s website and upload the CSR where possible. For GoDaddy, the necessary form looks as follows:

Just copy and paste the contents from the yourdomain.csr file.

Step 4: Download Certificate from your Provider

Download the certificate from your provided/issuer. For instance, for godaddy.com, select the certificate for Tomcat.

Step 5: Installing the Certificates into your Keystore

You will need to install both the certificate for your server as well as some certificates from your issuer (see intermediary certificates).

Below we will install the certificates provided from GoDaddy. First, install the root certificates from GoDaddy into your keystore (the names for the crt files are different for different providers).

keytool -import -alias root -keystore tomcat.keystore -trustcacerts –file gd_bundle.crt

Then, install the intermediary certificates:

keytool -import -alias intermed -keystore tomcat.keystore -trustcacerts –file gd_intermediate.crt

The tool might prompt you that the “Certificate already exists in keystore under alias <root>”. Type “yes” to add it in any case.

Lastly, install the certificate for your server:

keytool -import -alias tomcat -keystore tomcat.keystore -trustcacerts –file yourdomain.com

This time, the tool should report “Certificate reply was installed in keystore”.

The result of this procedure should be that the tomcat.keystore file should have grown in size to about 8 kb (from 3 kb after step 2).

Optional: Also download the ‘Go Daddy Class 2 Certification Authority Root Certificate‘ from the godaddy website and add it to your store. Add it with the alias ‘root2’.

Step 6: Double-Check you have Installed all Certificates

Use to keytool to verify that you have all certificates installed correctly.

keytool –list –keystore tomcat.keystore

This should show you that your keystore contains three entries: ‘root’, ‘intermed’ and ‘tomcat’. (And ‘root2’ if you have added the Go Daddy Class2 certificate).

Step 7: Prepare Keystore for Netty

There are many ways to provide the keystore we have just create to Netty. The following is just one option (but one I find particularly handy):

1. Convert your keystore into a String using Base64Coder and the OneUtils.

final File original = new File(pathtoyourkeystore);

System.out.println(Base64Coder.encode(

OneUtilsJre.toByteArray(new FileInputStream(original))));

2. Copy the String and place it into a static variable, for instance:

class MyKeystore {

public static data = "[generated base 64 data]";

}

3. Create an SSLContext from the data of your keystore.

SSLContext serverContext = SSLContext.getInstance("TLS");

final KeyStore ks = KeyStore.getInstance("JKS");

ks.load(new ByteArrayInputStream(Base64Coder

.decode(MyKeystore.data)),

"yourkeystorepassword".toCharArray());

final KeyManagerFactory kmf = KeyManagerFactory

.getInstance(algorithm);

kmf.init(ks, "yourkeystorepassword".toCharArray());

serverContext.init(kmf.getKeyManagers(), null, null);

4. Create a Netty SSLHandler from the created context:

final SslHandler sslHandler = new SslHandler(serverContext);

5. Add the SSL handler to your Netty pipe (remember this must be the first handler):

pipeline.addLast("ssl", sslHandler);

Now deploy to server and enjoy the SSL security.

References

Generating a CSR and Installing an SSL Certificate in Tomcat 4.x/5.x/6.x

Tomcat 5 SSL – Install GoDaddy Wildcard Certificate JKS / PKCS12 ? What?

Eclipse Wiki – Generating a Private Key and a Keystore

Why Netty cannot serve multiple SSL domains from one IP

Background

Due to some issues with a transparent proxy apparently employed by Vodafone New Zealand, a signed SSL certificate had to be added to the REST server in the Appjangle cloud in order to serve resources ‘protected’ from Vodafone’s caching efforts.

One REST server in the Appjangle cloud can serve more than one domain … but this appears to be troublesome to achieve using SSL.

Problem

You would like to serve content through HTTPS from two domains from one IP address using Netty. For example:

https://mydomain1.com

and https://mydomain2.com

both should be served from a Netty server running on the IP 184.2.23.1.

Analysis

It is relatively easy to host multiple HTTP hosts on one IP address. One can implement a SimpleChannelUpstreamHandler arranged in a pipeline after a HttpRequestDecoder. The SimpleChannelUpstramHandler can then separate requests based on the HOST value of the incoming HttpRequests.

For SSL, this is not possible, since the SslHandler is usually defined at the very beginning of a Netty pipeline. This is an inherent requirement of the SSL protocol, which protects communication with an IP address and not with a domain.

It is therefore not possible to ‘unwrap’ the incoming encoded message and retrieve its HOST value, since this can only be done AFTER the SSL connection is established.

Note: This is not an inherent problem of Netty but caused by the JDK’s SSL implementation.

Solution

One possible solution would be to use Server Name Indication – an extension to the SSL protocol to allow for ‘virtual hosts’ over SSL. However, this is extension not necessarily supported by all available HTTP clients. Moreover, it does not appear that Netty/Java currently support Server Name Indication.

Therefore, the best option at present appears to use one dedicated IP address for every HTTPS host you want to use.

Also note that JDK 7 adds support for Server Name Indication, so if you are running on this platform, you could explore if you can configure Netty to support it.