Friday, August 10, 2018

Certificate check and installation (Java)

Been dealing with self signed certificate quite sometimes and found myself always googled around for the how-tos, guess it's time to write it down here (for checking back later on which I guess I will... ;)

And here's the famous security exception:
PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target;
nested exception is 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

Goal is to install a self signed certificate in Java keystore so that Java app can open https connection to the server without raising any security error or trying to skip the security checking at all.


How to:

Step 1. Extracting the certificate
Using openssl:
1. Grab the target certificate from the server
openssl s_client -showcerts -verify 5 -connect {HOST:PORT} | tee thecert.txt
Type QUIT and press enter/return, certificate will be captured in thecert.txt
 2. Generate cert file
openssl x509 -inform PEM -in thecert.txt -out thecert.crt
3. Verify cert
openssl x509 -in thecert.crt -text -noout

In case you are dealing with a development environment, you might want to install the root and intermediate cert in your keystore so that you don't have to import each and every certificate that belongs to another system integrated. See below on how to extract the root and intermediate cert.

Step 2. Installing the certificate
Next is to install the extracted certificate in the keystore, one way is to install it right on the jre's keystore and the more secure way is to setup a local truststore and pass it as JVM parameter (e.g. -Djavax.net.ssl.trustStore=./LocalTrustStore)
1. Import the certificate
     keytool -import -alias {THE_ALIAS} -keystore {PATH_TO_KEYSTORE} -file {CERTIFICATE FILE}
    Default jre keystore can be found under jre/lib/security directory.
2. Verify it
   keytool -list -keystore {PATH_TO_KEYSTORE} -alias {THE_ALIAS}

Step 3. Testing using SSLPoke
Get SSLPoke here, it's one nice utility to check whether you have successfully import the certificate or not.
java SSLPoke {URL} {PORT}
e.g. java SSLPoke myserver 1234



Reference:

1. https://operational.io/openssl-commonly-used-commands/
2. https://gist.github.com/4ndrej/4547029
2. Extract root and intermediate
  1. openssl x509 -in cert.x509 -text Find the URL of the signing certificate.
  2. curl (url) >signer.der Download the signing certificate to a file (DER format in my case).
  3. openssl x509 -inform der -in signer.der -out signer.pem Convert signing certificate to PEM (X.509) format.
  4. openssl x509 -in signer.pem -text Confirm your results. Repeat procedure as necessary all the way up the certificate chain.