Fix certificate problem in HTTPSTag(s): Networking
HTTPS protocol is supported since JDK1.4 (AFAIK), you have nothing special to do.
import java.io.InputStreamReader; import java.io.Reader; import java.net.URL; import java.net.URLConnection; public class ConnectHttps { public static void main(String[] args) throws Exception { URL url = new URL("https://www.rgagnon.com/howto.html"); URLConnection con = url.openConnection(); Reader reader = new InputStreamReader(con.getInputStream()); while (true) { int ch = reader.read(); if (ch==-1) { break; } System.out.print((char)ch); } } }
Exception in thread "main" 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
The fix is to add the self signed certificate to trusted CAs on the client side. You do that by updating the CACERT file in the your JRE_HOME/lib directory.
Check this tutorial : http://www.java-samples.com/showtutorial.php?tutorialid=210 or follow this procedure :
- Export the certificate from your web browser.
- In Google Chrome, open the endpoint url, then press F12, then go to security tab in Developer window.
- Click "View Certificate", go to Details tab, and export to a .cer file (click "Copy to file", and just follow the wizard using default settings at each step).
- Now that you have your .cer file, you need to update the cacerts in your JRE installation. The keytool utility (included in your Java installation) is used to do that.
- Open a cmd with admin rights, then navigate to the bin directory of your java installation, and run the following command :
keytool -import -alias myNewCertificate -file "/path/to/mycert.cer" -keystore "<JRE_HOME>\lib\security\cacerts" -storepass changeit
where /path/to/mycert.cer is the absolute path to your .cer file created in the first step and
replace "JRE_HOME" with the path to your java installation (can be something like c:\Program Files\Java\jre1.8.0_131).
- Open a cmd with admin rights, then navigate to the bin directory of your java installation, and run the following command :
Or you can override the check and accept an untrusted certificate (with the risk coming with it! It's a HACK and should not be used in code in production).
import java.io.InputStreamReader; import java.io.Reader; import java.net.URL; import java.net.URLConnection; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSession; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import java.security.cert.X509Certificate; public class ConnectHttps { public static void main(String[] args) throws Exception { /* * fix for * Exception in thread "main" 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 */ TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() { public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } public void checkClientTrusted(X509Certificate[] certs, String authType) { } public void checkServerTrusted(X509Certificate[] certs, String authType) { } } }; SSLContext sc = SSLContext.getInstance("SSL"); sc.init(null, trustAllCerts, new java.security.SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); // Create all-trusting host name verifier HostnameVerifier allHostsValid = new HostnameVerifier() { public boolean verify(String hostname, SSLSession session) { return true; } }; // Install the all-trusting host verifier HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid); /* * end of the fix */ URL url = new URL("https://securewebsitewithuntrustedcertificate.com"); URLConnection con = url.openConnection(); Reader reader = new InputStreamReader(con.getInputStream()); while (true) { int ch = reader.read(); if (ch==-1) { break; } System.out.print((char)ch); } } }