How to Properly Import a Selfsigned Certificate into Java Keystore That Is Available to All Java Applications by Default?
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...
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
On Windows the easiest way is to use the program portecle.
- Download and install portecle.
- First make 100% sure you know which JRE or JDK is being used to run your program. On a 64 bit Windows 7 there could be quite a few JREs. Process Explorer can help you with this or you can use:
System.out.println(System.getProperty("java.home")); - Copy the file JAVA_HOME\lib\security\cacerts to another folder.
- In Portecle click File > Open Keystore File
- Select the cacerts file
- Enter this password: changeit
- Click Tools > Import Trusted Certificate
- Browse for the file mycertificate.pem
- Click Import
- Click OK for the warning about the trust path.
- Click OK when it displays the details about the certificate.
- Click Yes to accept the certificate as trusted.
- When it asks for an alias click OK and click OK again when it says it has imported the certificate.
- Click save. Don’t forget this or the change is discarded.
- Copy the file cacerts back where you found it.
On Linux:
You can download the SSL certificate from a web server that is already using it like this:
$ echo -n | openssl s_client -connect | \
sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > /tmp/examplecert.crt
Optionally verify the certificate information:
$ openssl x509 -in /tmp/examplecert.crt -text
Import the certificate into the Java cacerts keystore:
$ keytool -import -trustcacerts -keystore /opt/java/jre/lib/security/cacerts \
-storepass changeit -noprompt -alias mycert -file /tmp/examplecert.crt
D:\Java\jdk1.5.0_10\bin\keytool -import -file "D:\Certificates\SDS services\Dev\dev-sdsservices-was8.infavig.com.cer" -keystore "D:\Java\jdk1.5.0_10\jre\lib\security\cacerts" -alias "sds certificate"
I ended up writing a small script that adds the certificates to the keystores, so it is much easier to use.
You can get the latest version from
#!/bin/bash
# version 1.0
#
REMHOST=$1
REMPORT=${2:-443}
KEYSTORE_PASS=changeit
KEYTOOL="sudo keytool"
# /etc/java-6-sun/security/cacerts
for CACERTS in /usr/lib/jvm/java-8-oracle/jre/lib/security/cacerts \
/usr/lib/jvm/java-7-oracle/jre/lib/security/cacerts \
"/System/Library/Java/JavaVirtualMachines/" \
"/Applications/ "
do
if [ -e "$CACERTS" ]
then
echo --- Adding certs to $CACERTS
# FYI: the default keystore is located in ~/.keystore
if [ -z "$REMHOST" ]
then
echo "ERROR: Please specify the server name to import the certificatin from, eventually followed by the port number, if other than 443."
exit 1
fi
set -e
rm -f $REMHOST:$REMPORT.pem
if openssl s_client -connect $REMHOST:$REMPORT 1>/tmp/keytool_stdout 2>/tmp/output </dev/null
then
:
else
cat /tmp/keytool_stdout
cat /tmp/output
exit 1
fi
if sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' </tmp/keytool_stdout > /tmp/$REMHOST:$REMPORT.pem
then
:
else
echo "ERROR: Unable to extract the certificate from $REMHOST:$REMPORT ($?)"
cat /tmp/output
fi
if $KEYTOOL -list -storepass ${KEYSTORE_PASS} -alias $REMHOST:$REMPORT >/dev/null
then
echo "Key of $REMHOST already found, skipping it."
else
$KEYTOOL -import -trustcacerts -noprompt -storepass ${KEYSTORE_PASS} -alias $REMHOST:$REMPORT -file /tmp/$REMHOST:$REMPORT.pem
fi
if $KEYTOOL -list -storepass ${KEYSTORE_PASS} -alias $REMHOST:$REMPORT -keystore "$CACERTS" >/dev/null
then
echo "Key of $REMHOST already found in cacerts, skipping it."
else
$KEYTOOL -import -trustcacerts -noprompt -keystore "$CACERTS" -storepass ${KEYSTORE_PASS} -alias $REMHOST:$REMPORT -file /tmp/$REMHOST:$REMPORT.pem
fi
fi
done
This worked for me. :)
sudo keytool -importcert -file filename.cer -alias randomaliasname -keystore $JAVA_HOME/jre/lib/security/cacerts -storepass changeit
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.
Must Read
Java 9+
So with Java 9 (aka Java 1.9) or later, simply use
keytool -importcert -trustcacerts -cacerts -file myCert.pem -alias myCert