How to properly import a selfsigned certificate into Java keystore that is available to all Java applications by default?

Viewed 468143

I do want to import a self signed certificate into Java so any Java application that will try to establish a SSL connection will trust this certificate.

So far, I managed to import it in

keytool -import -trustcacerts -noprompt -storepass changeit -alias $REMHOST -file $REMHOST.pem
keytool -import -trustcacerts -noprompt -keystore cacerts -storepass changeit -alias $REMHOST -file $REMHOST.pem

Still, when I try to run HTTPSClient.class I still get:

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 target
11 Answers

You can use keytool with your Java installation which should be in $JAVA_HOME/bin. The Java keystore is located in $JAVA_HOME/lib/security/cacerts or $JAVA_HOME/jre/lib/security/cacerts which depends on if you have the JDK or JRE installed.

If using Java 9 or later, you don't need to know the exact location. You can use the -cacerts option as a shortcut.

Java 9+

So with Java 9 (aka Java 1.9) or later, simply use

keytool -importcert -trustcacerts -cacerts -file myCert.pem -alias myCert

Earlier Java versions

With Java 8 (aka 1.8) or older, you must specify the keystore location like so

keytool -importcert -trustcacerts -keystore $JAVA_HOME/lib/security/cacerts -file myCert.pem -alias myCert

With Java 5 (aka 1.5) or older, the -importcert option did not exist. It was called -import, but otherwise it's identical. So use

keytool -import -trustcacerts -keystore $JAVA_HOME/lib/security/cacerts -file myCert.pem -alias myCert

Additional options

  • You will be asked for the truststore password, The default password is changeit.
  • If you need to run the import unattended, you can add -storepass changeit -noprompt

Formats

keytool can import X.509 v1, v2, and v3 certificates, and PKCS#7 formatted certificate chains consisting of certificates of that type (P7B). The data to be imported must be provided

  • either in binary encoding format (DER)
  • or in printable encoding format (aka base64 encoded), enclosed in -----BEGIN and -----END lines (PEM)

Note: I'm not sure if certificate chains in PEM format really work.

Bonus script

I'm afraid, it's bash, so no solution for Windows users.

This simple script, created thanks to several useful questions and smart answers here on stackoverflow, checks the Java version and - if necessary - determines the correct keystore location, and it can import multiple certificates in one command. Note that you must pass the file pattern argument in single quotes (see usage).

addcerts.sh

#!/bin/bash

# Add custom root certificates to Java trust store

if [ "$#" -ne 1 ]; then
    SCRIPT=`basename "$0"`
    echo "Usage: $SCRIPT 'path/to/certs/*'"
    exit 1
fi

CERTFILES=$1    

JAVA_VERSION=`java -version 2>&1 | head -1 | cut -d'"' -f2 | sed '/^1\./s///' | cut -d'.' -f1`

if (( $JAVA_VERSION >= 9 )); then
    CACERTS="-cacerts"
else    
    # Check where cacerts are located
    # differs depending or jdk or jre installed
    if [ -d "$JAVA_HOME/jre" ]; then
        CACERTS="$JAVA_HOME/jre"
    else
        CACERTS="$JAVA_HOME"
    fi
    CACERTS="-keystore $CACERTS/lib/security/cacerts"   
fi      

# Now add certificates 
for CERTFILE in $CERTFILES; do
    # Remove path, then suffix to derive alias from filename
    ALIAS=${CERTFILE##*/}  
    ALIAS=${ALIAS%.*}
    $JAVA_HOME/bin/keytool -importcert -file "$CERTFILE" -alias "$ALIAS" $CACERTS -trustcacerts -storepass changeit -noprompt
    if [ $? -ne 0 ]; then
        echo "Failed to add $CERTFILE as $ALIAS to $CACERTS"
        exit 1
    fi  
done

Fist get the certificate from the provider. Create a file ends with .cer and paste the certificate.

Copy the text file or paste it somewhere you can access it then use the cmd prompt as an admin and cd to the bin of the jdk; the command that will be used is the: keytool

Change the password of the keystore with:

keytool -storepasswd -keystore "path of the key store from c\ and down"

The password is : changeit

Then you will be asked to enter the new password twice. Then type the following:

keytool -importcert -file "C:\Program Files\Java\jdk-13.0.2\lib\security\certificateFile.cer" -alias chooseAname -keystore  "C:\Program Files\Java\jdk-13.0.2\lib\security\cacerts"

install certificate in java linux

/opt/jdk(version)/bin/keytool -import -alias aliasname -file certificate.cer -keystore cacerts -storepass password

In Windows these commands work on the command line:

cd C:\Program Files\Java\jre1.8.0_301\lib\security\
keytool -import -trustcacerts -alias cert_ssl -file C:\opt\esb-config\keystores\cert.cer -noprompt -storepass changeit -keystore cacerts

changeit is the default password for the trust store.

Related