Troubleshoot Java with self-signed certificates

Problem PKIX path building failed

You try to access SSL secured services using self-signed certificates with a Java application. You can’t access the service and you get an exception:

sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested 
.
.
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
.
.
-

Diagnosis

To diagnose if your certificate is correctly stored in a trust store file, you can use SSLPoke to test if a connection with your custom trust store can be established.

Step 1: Download the SSLPoke executable jar file

wget https://github.com/opennms-forge/SSLPoke/releases/download/1.0/SSLPoke-1.0.jar

Step 2: Run the command and test if you can establish a connection

java -Djavax.net.debug=ssl  \
       -Djavax.net.ssl.trustStore=<path/to/your/trust-store.pkcs12> \
       -jar SSLPoke-1.0.jar \
       <host-or-ip> <port>

:warning: OpenJDK 9+ use trust stores in PKCS12 format by default. OpenJDK 8 is using the jks format.

Problem Trust Anchors parameter must be non-empty

When you provide a trust store file and you get the following exception:

javax.net.ssl.SSLException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
	at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:133)
	at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:349)
	at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:292)
	at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:287)
	at java.base/sun.security.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1609)
	at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:465)
	at java.base/sun.security.ssl.SSLSocketImpl.ensureNegotiated(SSLSocketImpl.java:841)
	at java.base/sun.security.ssl.SSLSocketImpl$AppOutputStream.write(SSLSocketImpl.java:1211)
	at java.base/sun.security.ssl.SSLSocketImpl$AppOutputStream.write(SSLSocketImpl.java:1183)
	at sk.mhecko.ssl.SSLPoke.main(SSLPoke.java:27)
Caused by: java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
	at java.base/sun.security.validator.PKIXValidator.<init>(PKIXValidator.java:102)
	at java.base/sun.security.validator.Validator.getInstance(Validator.java:181)
	at java.base/sun.security.ssl.X509TrustManagerImpl.getValidator(X509TrustManagerImpl.java:300)
	at java.base/sun.security.ssl.X509TrustManagerImpl.checkTrustedInit(X509TrustManagerImpl.java:176)
	at java.base/sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:189)
	at java.base/sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:129)
	at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.checkServerCerts(CertificateMessage.java:1341)
	at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.onConsumeCertificate(CertificateMessage.java:1232)
	at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.consume(CertificateMessage.java:1175)
	at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:392)
	at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:443)
	at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:421)
	at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:182)
	at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:172)
	at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1426)
	at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1336)
	at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:450)
	... 4 more
Caused by: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
	at java.base/java.security.cert.PKIXParameters.setTrustAnchors(PKIXParameters.java:200)
	at java.base/java.security.cert.PKIXParameters.<init>(PKIXParameters.java:120)
	at java.base/java.security.cert.PKIXBuilderParameters.<init>(PKIXBuilderParameters.java:104)
	at java.base/sun.security.validator.PKIXValidator.<init>(PKIXValidator.java:99)
	... 20 more

The problem is mainly around using your trust store file. You can see more details when you use the -Djavax.net.debug=all setting while running the SSLPoke tool. Verify the following issues:

  • Path and access to the trust store file
  • Make sure you provide the correct password -Djavax.net.ssl.trustStorePassword
  • trustStore file is not empty, you can use the KeyStore Explorer to verify the content.

If you still get the exception

Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at java.base/sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
	at java.base/sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
	at java.base/java.security.cert.CertPathBuilder.build(CertPathBuilder.java:297)
	at java.base/sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:434)
	... 20 more

Ensure you have your Root-CA certificate and intermediate certificates added to your trust store as well.

2 Likes

I am trying this as I am getting a PKIX error, but I get the following response when I try the command:
Usage: sk.mhecko.ssl.SSLPoke <host> <port>

Can you try to change the order of the arguments? I think the -jar <host-or-ip> <port> should be the last arguments. If that works we should fix the run command in Step 2.

1 Like

That was it. I updated the original post to match.
Thanks.

Thank you very much :ok_hand: