🛡️ Using Self-Signed Certificates with Java-Based Applications
Java applications often rely on TLS for secure communication. However, when IT organizations issue self-signed or internally signed SSL certificates, these certificates typically aren't recognized by Java's default trust store. This can result in SSL handshake errors like:
PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException:
unable to find valid certification path to requested target
This article explores the root cause of this issue, walks through solutions across Windows and Linux environments, and covers how to integrate trusted certs into Docker images—specifically for OpenLegacy’s openlegacy/hub-enterprise:latest
.
⚠️ The Problem: Untrusted Certificates
When Java initiates an SSL/TLS connection, it verifies the server's certificate against its trust store (cacerts
). If your Java application accesses a server with a self-signed certificate or one issued by an internal CA, Java will reject the connection unless the certificate is added to the trust store.
🧰 Solution Overview
The solution involves importing the relevant certificate chain—ideally starting from the root CA or intermediate CA certificate—into the Java trust store. This allows Java to properly validate the server certificate against a known issuer
Important: Don’t just grab the server’s public certificate. You’ll need the Certificate Authority (CA) certificate that issued it (either the root CA or intermediate CA). This is what Java needs to trust the server and build a complete certification path
Step 1: Export the Certificate
🏢 Exporting CA Certificate from Internal Certificate Authority (e.g., Windows CA Server)
If your organization uses an internal Microsoft CA:
-
Open Certificate Authority Management Console on the CA server:
- Run
certsrv.msc
or open via Server Manager.
- Run
-
Go to the Certification Authority Root Node:
- This displays the CA name (e.g.,
Corp-CA
).
- This displays the CA name (e.g.,
-
Right-click the CA Name → All Tasks → Export CA Certificate:
- Choose to export as
Base64 encoded X.509 (.CER)
.
- Choose to export as
-
Save the
.cer
file to a location accessible to you.
🌐 Exporting CA from Browser (if already trusted)
If you're connecting to a server that’s already trusted by your browser:
In Chrome or Edge:
- Navigate to the secure site (e.g.,
https://internal-server
). - Click the padlock icon → Certificate → Certification Path.
- Select the top-level certificate in the path (this is the CA).
- Click "View Certificate" → "Details" → "Copy to File".
- Choose Base64 encoded X.509 (.CER) and export.
🔍 Exporting CA from Server Using OpenSSL
If you’re accessing an internal service and you don’t have GUI access:
openssl s_client -connect server.domain.com:443 -showcerts
- You’ll see the full certificate chain.
- Copy the top-most certificate block (
-----BEGIN CERTIFICATE-----
...). - Save it as
ca-cert.pem
.
You can also inspect and verify with:
openssl x509 -in ca-cert.pem -text -noout
Look for Issuer
and Subject
—they’ll often be the same for a self-signed CA.
🖥️ Adding Certificate on Windows (Local Java Environment)
Step 2: Locate the Java cacerts
Trust Store
cacerts
Trust StoreDefault location:
C:\Program Files\Java\jdk<version>\lib\security\cacerts
Step 3: Import the Certificate
Open Command Prompt as administrator and run:
keytool -import -alias customcert -keystore "C:\Program Files\Java\jdk<version>\lib\security\cacerts" -file customcert.pem
- Default password:
changeit
- You’ll be asked to confirm the certificate trust.
🐧 Adding Certificate on Linux-Based Server
Locate Java cacerts
(common paths)
cacerts
(common paths)/usr/lib/jvm/java-<version>/lib/security/cacerts
Or use:
readlink -f $(which java)
Import the Certificate
sudo keytool -import -alias customcert -keystore /path/to/cacerts -file customcert.pem
Confirm trust and enter the password (changeit
).
🐳 Adding Certificate to OpenLegacy Docker Image
To integrate certificates into Docker containers like openlegacy/hub-enterprise:latest
, follow these steps:
Extend the Docker Image
Create a Dockerfile:
FROM openlegacy/hub-enterprise:latest
COPY customcert.pem /tmp/customcert.pem
RUN keytool -import -alias customcert -keystore $JAVA_HOME/lib/security/cacerts \
-file /tmp/customcert.pem -storepass changeit -noprompt
RUN rm /tmp/customcert.pem
Then build your image:
docker build -t openlegacy/hub-enterprise:latest-custom-ca .
Use this image instead of the default when starting your container.
🕵️ Final Tips
- Always back up your original
cacerts
before modifying it. - For production, consider using a Certificate Authority or internal CA with root cert added organization-wide.
Updated 2 days ago