SSL Certificate Guide

Transport Layer Security (TLS) Self-Signed Certificates

Self-signed server TLS certificates are useful for testing server TLS configuration or for personal use when encrypting communication over HTTP.

These types of certificates are considered untrustworthy because the certificate identity has not been signed/verified by a third party certificate authority (CA). Otherwise, a self-signed certificate still ensures that communication over HTTPS is encrypted.

For long term server use, Sonatype recommends getting a certificate signed by a CA.

Generating Self Signed Server TLS Certificates

The following steps use Oracle Java 7+ keytool (Unix/Windows) to generate self-signed server certificates which can be used with Sonatype server products.

Openssl is needed only when creating certificates for use in a reverse proxy such as Apache or nginx.

What are keystores and truststores?

Where does a Java client load trusted certificates from?

A Java client program loads trusted certificates from the following locations, in this order:

a file specified by the system property javax.net.ssl.trustStore. This property is not set by default. If set, but the file does not exist, no truststore is used.

if java-home/lib/security/jssecacerts is a valid file, trusted certificates are loaded from here. This file does not exist by default but can be created by a user using keytool.

java-home/lib/security/cacerts exists by default. It is pre-loaded with well known public certificate authority root certificates that allow a client program to trust sites which have certificates signed by them. If for some reason it is missing, there will be no trusted certificates loaded into the client.

When does the file ~/.keystore get used?

The keytool program creates or reads this file whenever the -keystore argument is not provided to the keytool program.

Java client programs do not normally read this file when looking for trusted certificates. This file is intended to hold user specific private keys.

Therefore, importing a remote server certificate into ~/.keystore will not usually resolve issues where trust of the remote server cannot be established . ie. solving PKIX path building failed errors.

Common keytool Operations

Here are some common keytool operations that are needed when managing SSL certificates.

Always use the full path to your keytool executable and your intended target keystore file when executing keytool. Do this with the -keystore parameter. This helps avoid confusion about which keystore files are being modified.Usually you will want the keytool to manipulate the system wide truststore file at java-home/lib/security/jssecacerts or java-home/lib/security/cacerts

If you are using a system wide default JSSE keystore location on either a Linux,Solaris or OSX platform, you must run the commands as the root user. You can do this either by changing to the root user (su -) first, or by using the sudo command: sudo [command].

On Windows, open a command prompt as an Administrator.

The default password used by Java for the built-in keystore is changeit. If your key-store uses a different password, you'll need to specify that password as the -storepass parameter.

Getting a Remote Certificate

This command connects to a remote server on a specific port and prints the SSL certificate to a file.

keytool -printcert -rfc -sslserver example.com:443 > example.pem

Examining Certificate File Details

To verify the validity of a certificate, you must visually examine the contents in human readable (non-rfc) form. Each certificate in the chain will be demarcated by a line containing Certificate[n]:, where n is the order number of the certificate.

keytool -printcert -file example.pem

Getting a Remote Certificate Through A HTTP Proxy Server

Sometimes your HTTP Proxy server may be modifying the remote certificate. In that case it is important that keytool uses the proxy server when fetching the certificate. Use special -J options to do this.

On recent Windows systems and on Gnome 2.x systems it is possible to tell keytool to use the system proxy settings (both these systems let you set proxies globally through their user interface). In that case, use the following:

Replace <proxy_hostname> and <proxy_port> with the HTTP proxy server that Nexus is configured with under Administration -> Server. Replace <remote_host_name:remote_ssl_port> with one of the remote host and port having the certification problem. You can omit the port if it is the default 443.

Then, examine the certificate and look for the Certificate[n]: entry that has an Issuer: line that correlates to your HTTP proxy server. Usually this will be the last certificate.

You can then count that number of entries down, demarcated by -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- lines, in the encoded certificate file, and copy that certificate entirely to a new file ( including the begin and end certificate parts ). The new file then contains only the certificate of your HTTP proxy server.

Explicitly Trusting a Self-Signed or Private Certificate in a Java Based Client

If you generate a self-signed certificate, and want a Java based client to explicitly trust this certificate, then you need to make sure the trust store used your client, trusts at least one member of the certificate chain.

Suppose you have a server at https://example.com using a self-signed or private certificate:

(Required) Get the certificate from the server into a PEM encoded file on your Java client host:

keytool -printcert -rfc -sslserver example.com > example.pem

(Optional/Advised) Inspect the certificate you just downloaded to verify it looks OK:

keytool -printcert -file example.pem

(Required) Import the certificate into the default Java truststore location under a relevant alias, using the default truststore password:

Forcing Apache Maven to Implicitly Trust a Self-Signed Certificate

Apache Maven has a system property maven.wagon.http.ssl.insecure that can be set to implicitly trust a self-signed certificate from a HTTPS remote repository.

The system property will only work if:

it is set in the environment variable MAVEN_OPTS

the remote certificate has a single certificate in the certificate chain ( ie. self-signed)

The property will not work at mvn invocation time. For example, this will not work: mvn -Dmaven.wagon.http.ssl.insecure=true install

You must set this instead inside the MAVEN_OPTS environment variable value.

One method to do this explicitly to Maven, is to create a file $HOME/.mavenrc ( or on Windows %HOME%/.mavenrc ) and set MAVEN_OPTS in there. This file will be sourced every time you invoke Maven.

Forcing Apache Maven to Trust A Certificate Issued by An Organizational Certificate Authority

When your organization has a private certificate authority issuing server certificates, a common problem is that the system property maven.wagon.http.ssl.insecure will not help. This is because the certificate chain used by the Nexus HTTPS connection contains more than one certificate. The certificate chain hierarchy might look something like this:

Each branch in the tree is a certificate - so this chain contains 4 certificates.

The Maven property checks if the chain contains only one certificate, which implies it is self-signed. If it contains more than one as above, and none of the other certificates are in the Java trust store used by the Java process running Maven, then the only workarounds are to explicitly import the server certificate into the default truststore or have the Nexus server certificate chain be signed by a public certificate authority already in the default Java trust store.

Querying Remote SSL Protocol and Cipher Support

Some secure connection problems may occur because the remote does not support a protocol or cipher needed by the client. There is a tool called nmap you can use to see what protocols are supported by the remote.

Below is an example command and output that tests a secure connection to localhost:8453 :