Ubuntu 18.04 and Debian Java 9, 10 and 11 cacerts
file is now in the pkcs12
format,
and requires a password to open.
It used to be in the jks
format, which worked fine with an default ("changeit") and empty passwords.
(CA certificates are public information, and only very very rarely would they need to be secret, for a very specific business need you would be aware of.)
Java programs which need to use JDK's SSL functionality have to access the cacerts
file, and the only way to get the decryption password to the JVM is by using the
-Djavax.net.ssl.trustStorePassword=changeit
command line parameter.
If you don't set that parameter when starting your JVM, it uses the default empty password (""), which is how you get the error message:
java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
which must have placed high in the "least informative error message of 2018" competition.
/usr/bin/printf '\xfe\xed\xfe\xed\x00\x00\x00\x02\x00\x00\x00\x00\xe2\x68\x6e\x45\xfb\x43\xdf\xa4\xd9\x92\xdd\x41\xce\xb6\xb2\x1c\x63\x30\xd7\x92' > /etc/ssl/certs/java/cacerts
/var/lib/dpkg/info/ca-certificates-java.postinst configure
https://gist.github.com/mikaelhg/527204e746984cf9a33f7910bb8b4cb6
docker-library/openjdk/issues/145
Ubuntu 1769013: Please merge ca-certificates-java 20180413 (main) from Debian unstable (main)
Ubuntu 1739631: Fresh install with JDK 9 can't use the generated PKCS12 cacerts keystore file
JEP 229: Create PKCS12 Keystores by Default
JDK-8044445 : JEP 229: Create PKCS12 Keystores by Default
Debian ca-certificates-java ChangeLog
See what your JDK's SSL stack is doing with
-Djavax.net.debug=ssl:handshake
Generate empty passwordless JKS keystore files with
pip3 install pyjks
python3 generate_empty_jks_keystore.py
javac --release 8 GenerateEmptyJKSKeystore.java
java -cp . GenerateEmptyJKSKeystore
Attempt a SSL connection to see if your JVM can access the cacerts
file
java -cp . TestHttps 'https://www.google.com/'
java -Djavax.net.ssl.trustStorePassword=changeit -cp . TestHttps "https://www.google.com/"
Build an Ubuntu 18.04 Docker image with this workaround:
docker build --pull -t bjc .
Test that image. A stack trace is a failure, an empty line is a success:
docker run -it --rm bjc
Test various solutions on different platforms:
docker run -it --rm -v `pwd`:/app:ro -w /app ubuntu:18.04 bash tests/test_01.sh
docker run -it --rm -v `pwd`:/app:ro -w /app ubuntu:18.04 bash tests/test_02.sh
docker run -it --rm -v `pwd`:/app:ro -w /app ubuntu:18.04 bash tests/test_03.sh
docker run -it --rm -v `pwd`:/app:ro -w /app ubuntu:18.04 bash tests/test_04.sh
docker run -it --rm -v `pwd`:/app:ro -w /app ubuntu:18.04 bash tests/test_05.sh
docker run -it --rm -v `pwd`:/app:ro -w /app debian:testing bash tests/test_01.sh
docker run -it --rm -v `pwd`:/app:ro -w /app debian:testing bash tests/test_02.sh
docker run -it --rm -v `pwd`:/app:ro -w /app debian:testing bash tests/test_03.sh
docker run -it --rm -v `pwd`:/app:ro -w /app debian:testing bash tests/test_04.sh
docker run -it --rm -v `pwd`:/app:ro -w /app debian:testing bash tests/test_05.sh
javax.net.ssl.SSLException: java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
at java.base/sun.security.ssl.Alerts.getSSLException(Alerts.java:214)
at java.base/sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1974)
at java.base/sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1926)
at java.base/sun.security.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1909)
at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1436)
at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1413)
at java.base/sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:567)
at java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1581)
at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1509)
at java.base/java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:527)
at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:329)
at TestHttps.main(TestHttps.java:8)
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:89)
at java.base/sun.security.validator.Validator.getInstance(Validator.java:181)
at java.base/sun.security.ssl.X509TrustManagerImpl.getValidator(X509TrustManagerImpl.java:330)
at java.base/sun.security.ssl.X509TrustManagerImpl.checkTrustedInit(X509TrustManagerImpl.java:180)
at java.base/sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:192)
at java.base/sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:133)
at java.base/sun.security.ssl.ClientHandshaker.checkServerCerts(ClientHandshaker.java:1947)
at java.base/sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1777)
at java.base/sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:264)
at java.base/sun.security.ssl.Handshaker.processLoop(Handshaker.java:1098)
at java.base/sun.security.ssl.Handshaker.processRecord(Handshaker.java:1026)
at java.base/sun.security.ssl.SSLSocketImpl.processInputRecord(SSLSocketImpl.java:1137)
at java.base/sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1074)
at java.base/sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:973)
at java.base/sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1402)
at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1429)
... 8 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:86)
... 23 more