Configure a Java HTTP Client to Accept Self-Signed Certificates
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> ...