Configure a Java HTTP Client to Accept Self-Signed Certificates

From NovaOrdis Knowledge Base
Jump to: navigation, search

Internal

Overview

If a Java client is attempting to connect to a HTTPS server configured with a self-signed SSL certificate, the Java client will fail with:

...
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

This article provides a solution to this problem. The solution consist in obtaining the HTTPS server's public key, importing it into a local truststore and configuring the Java client to use the local truststore.

Procedure

Obtain the HTTPS Server's Certificate

Use openssl s_client to obtain the server's certificate as described here. If we use Charles, Charles' root certificate can be exported as shown here. The response will include the server's certificate in PEM format, which should look similarly to:

-----BEGIN CERTIFICATE-----
MIIDqjCCAxOgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBmzELMAkGA1UEBhMCVVMx
EzARBgNVBAgTCkNhbGlmb3JuaWExFDASBgNVBAcTC1NhbnRhIENsYXJhMRowGAYD
VQQKExEzREdlbyBEZXZlbG9wbWVudDEMMAoGA1UECxQDUiZEMRgwFgYDVQQDEw9k
ZWx0YS4zZGdlby5jb20xHTAbBgkqhkiG9w0BCQEWDnJvb3RAM2RnZW8uY29tMB4X
DTA3MDMxMzAwMDA1MVoXDTEyMDMxMTAwMDA1MVowgZsxCzAJBgNVBAYTAlVTMRMw
EQYDVQQIEwpDYWxpZm9ybmlhMRQwEgYDVQQHEwtTYW50YSBDbGFyYTEaMBgGA1UE
ChMRM0RHZW8gRGV2ZWxvcG1lbnQxDDAKBgNVBAsUA1ImRDEYMBYGA1UEAxMPZGVs
dGEuM2RnZW8uY29tMR0wGwYJKoZIhvcNAQkBFg5yb290QDNkZ2VvLmNvbTCBnzAN
BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0Qr+rQFlXbb6Cno44THzb7FqS2RM1839
v/PEU5dg4Ct5Lru57r9DE3ZYeTqhvKKJoBU7CpubCWdkmiH8VioTz0wg3cWOT/NL
1S0SBMHpUo5L7NlNDVs7BYb8Ul6Zw3TJOEv5k1/WaM6zCSmW3lpQ6QfibwK+ytD7
Iv9plxyxmasCAwEAAaOB+zCB+DAdBgNVHQ4EFgQUy7r6eE8PrFjQUNZsS7tWyxt3
d+cwgcgGA1UdIwSBwDCBvYAUy7r6eE8PrFjQUNZsS7tWyxt3d+ehgaGkgZ4wgZsx
CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRQwEgYDVQQHEwtTYW50
YSBDbGFyYTEaMBgGA1UEChMRM0RHZW8gRGV2ZWxvcG1lbnQxDDAKBgNVBAsUA1Im
RDEYMBYGA1UEAxMPZGVsdGEuM2RnZW8uY29tMR0wGwYJKoZIhvcNAQkBFg5yb290
QDNkZ2VvLmNvbYIBADAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBAUAA4GBAGCT
Pdxif5spjhoZQCRvQ+ATW3Osr/yONkQqs+3F37X8mCegXp6ETwWHjclDSMtGy5wr
h1YSgfE29rAPNWhv+IIwORHgrBfa3HkEio7xZdSJMrCgC4Fgd/VrI8yqDFwWlybo
BMCgIbRNxq07R4zaz2GsO2lxruSrpwfS+xMWfpdM
-----END CERTIFICATE-----

Save it locally in a server-cert.pem file.

Note that multiple -----BEGIN CERTIFICATE-----/-----END CERTIFICATE----- blocks may be present.

Import the Certificate into a Local Truststore

Import the certificate into a local truststore, and declare it trusted while importing it:

keytool -import -alias <server-name> -keystore ./<server-name>.truststore -file server-cert.pem
keytool -import -alias nexus -keystore ./nexus.truststore -file server-cert.pem
Enter keystore password:
Re-enter new password:
Owner: CN=*.apps.openshift.novaordis.io
Issuer: CN=openshift-signer@1510385842
Serial number: 12
Valid from: Sat Nov 11 00:04:28 PST 2017 until: Mon Nov 11 00:04:29 PST 2019
Certificate fingerprints:
     MD5:  E0:B7:FA:9C:4F:01:66:1C:51:FC:F9:49:56:69:F8:88
     SHA1: FE:27:F4:0F:20:EA:A8:E4:1D:D4:F3:FD:81:4A:C8:06:35:1E:E5:1A
     SHA256: 3B:A8:06:B2:6F:49:27:1B:7A:50:67:42:E0:6B:E4:99:32:CC:22:21:F2:D4:26:B8:9D:21:BB:96:9D:CF:DD:FB
     Signature algorithm name: SHA256withRSA
     Version: 3

Extensions:

#1: ObjectId: 2.5.29.19 Criticality=true
BasicConstraints:[
 CA:false
 PathLen: undefined
]

#2: ObjectId: 2.5.29.37 Criticality=false
ExtendedKeyUsages [
 serverAuth
]

#3: ObjectId: 2.5.29.15 Criticality=true
KeyUsage [
 DigitalSignature
 Key_Encipherment
]

#4: ObjectId: 2.5.29.17 Criticality=false
SubjectAlternativeName [
 DNSName: *.apps.openshift.novaordis.io
 DNSName: apps.openshift.novaordis.io
]

Trust this certificate? [no]:  yes
Certificate was added to keystore

Configure the Java Client to use the Local Truststore

java -Djavax.net.ssl.trustStore=.../nexus.truststore -Djavax.net.ssl.trustStorePassword=<password> ...