When developing Java web or enterprise applications that connect to other web servers using HTTPS, encountering the javax.net.ssl.SSLHandshakeException
is not uncommon. This article provides a detailed guide on understanding and resolving this exception, specifically the sun.security.validator.ValidatorException
.
Understanding the SSL Handshake
When a Java client establishes a connection to a Java server, an SSL handshake takes place. During this process, the server returns certificates to confirm its identity. The client then validates these certificates against the root certificates stored in its truststore.
Key Insight: If the server returns a certificate that the client cannot validate against its truststore, the client throws the sun.security.validator.ValidatorException
.
The Core Issue: Certificate Validation
The primary reason for the javax.net.ssl.SSLHandshakeException
is the server returning certificates that aren't signed by a trusted Certification Authority (CA) present in the JRE's truststore. Examples of such trusted CAs include Verisign, Thawte, GoDaddy, and Entrust.
In simpler terms, the server sends an unrecognized certificate to the JRE, making it impossible for the JRE to validate the certificate against the private key in its truststore.
Keystore vs. Truststore: Know the Difference
It's essential to understand the distinction between a keystore and a truststore in Java:
- Keystore: Stores your credentials (server or client).
- Truststore: Stores credentials from Certification Authorities (CAs).
While both store certificates, their purposes differ. The keystore holds your credentials, while the truststore contains certificates from trusted CAs.
Common Scenarios: Internal Certificates
Often, servers send certificates from authorities not configured in the JRE's truststore. For instance, a server might send an internally signed certificate from a company. This scenario is frequent when connecting to internal servers, such as an LDAP server within an organization.
Resolving the Issue: Adding Certificates to the Truststore
To address the javax.net.ssl.SSLHandshakeException
, you must add the server's returned certificates to your JRE's truststore. This can be achieved using the keytool
or other tools provided by your organization.
Using InstallCert.java:
An open-source program, InstallCert.java
, can be used to add the server's certificates to the JRE's truststore. Running this program against the server and port will first attempt an SSL connection. If the "PKIX path building failed" error arises, the program will display the server's returned certificates. You can then add the certificate to the truststore.
Using Keytool:
The keytool
utility, bundled with the JDK installation, can also be employed to add certificates to the truststore. If you have access to the server's certificates, you can use the following command:
$ keytool -import -alias <alias-name> -file /path/to/certificate.cer -keystore cacerts
Conclusion
Understanding and resolving the javax.net.ssl.SSLHandshakeException
is crucial for developers working with Java applications that connect to servers using HTTPS. By ensuring that the server's certificates are added to the JRE's truststore, developers can ensure smooth and secure connections.