How to bypass certificate validation in the Java web service client

Use case: There is a web service hosted as https: // abcd / zz? Wsdl

What I would like to do is request this URI and, if I get the VALID WSDL, I return the boolean "true" else "false". Now, if I go through the Chrome browser to this URL, I will have to manually accept the cert warning prompt, and WSDL will then load. But how to do it through Java / HttpsURLConnection

import java.net.URL; import java.io.*; import javax.net.ssl.HttpsURLConnection; public class JavaHttpsExample { public static void main(String[] args) throws Exception { String httpsURL = "https://abcd/zz/V2.0/api?wsdl"; URL myurl = new URL(httpsURL); HttpsURLConnection con = (HttpsURLConnection)myurl.openConnection(); InputStream ins = con.getInputStream(); InputStreamReader isr = new InputStreamReader(ins); BufferedReader in = new BufferedReader(isr); String inputLine; while ((inputLine = in.readLine()) != null) { System.out.println(inputLine); } in.close(); } } 

and I get an error:

An exception in the "main" thread javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: no alternative object names corresponding IP address abcd found in com.sun.net.ssl.internal.ssl.Alerts.getSSLException ( Unknown source) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal (Unknown source) at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE (Unknown source) at com.sun.net. ssl.internal.ssl.Handshaker.fatalSE (Unknown source) at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate (Unknown Source) at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage ( Unknown Source) at com.sun.net.ssl.internal.ssl.Handshaker.processLoop (Unknown source) at com.sun.net.ssl.internal.ssl.Handshaker.process_record (Unknown Source) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord (Unknown source) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake (Unknown Source) at com.sun.net .ssl.internal.ssl.SSLSocketImpl.startHandshake (Unknown Source) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake (Unknown Source) at sun.net.www.protocol.https.HttpsClient.afterConnect (Unknown source) at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect (Unknown Source) at sun.net.www.protocol.http.HttpURLConnection.getInputStream (Unknown Source) at sun.net.www.protocol.https.HttpsURLConn .getInputStream (Unknown Source) in JavaHttpsExample.main (JavaHttpsExample.java:14) Called: java.security.cert.CertificateException: no alternative For the actual object names, the corresponding abcd IP address found in sun.security.util.HostnameChecker.matchIP (Unknown source) in sun.security.util.HostnameChecker.match (Unknown source) in com.sun.net.ssl.internal.ssl .X509TrustManagerImpl.checkIdentity (Unknown Source) at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted (Unknown Source)

i replaced the real IP with abcd (of course)

+4
source share
2 answers

Do not use a drowned TrustManager, as this makes your application reliable to everyone . I would recommend downloading the certificate provided on the site and adding it to the private trust keystore. This allows an exception to be made for this single site without allocation to all users.

I also like this approach because it does not require code changes.

In Chrome, click the lock icon to the left of the URL. Then click on "Certificate Information." Go to the "Details" tab and click "Copy to file." Save it as “base64 X.509 (.cer)” to “SITENAME.cer”.

Copy $ JAVA_HOME / lib / security / cacerts to your application directory as "mykeystore.jks".

Install the certificate using:

 keytool -keystore mykeystore.jks -storepass changeit -importcert -alias SITENAME -trustcacerts -file SITE.cer 

Now that you run your application, tell it to use a closed certificate store:

 java -Djavax.net.ssl.trustStore=mykeystore.jks ... 
+14
source

Just run your own trust manager, as in the code below.

 import java.net.URL; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.io.*; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; public class JavaHttpsExample { public static void main(String[] args) throws Exception { String httpsURL = "https://abcd/zz?wsdl"; URL myurl = new URL(httpsURL); SSLContext ssl = SSLContext.getInstance("TLSv1"); ssl.init(null, new TrustManager[]{new SimpleX509TrustManager()}, null); SSLSocketFactory factory = ssl.getSocketFactory(); HttpsURLConnection con = (HttpsURLConnection)myurl.openConnection(); con.setSSLSocketFactory(factory); InputStream ins = con.getInputStream(); InputStreamReader isr = new InputStreamReader(ins); BufferedReader in = new BufferedReader(isr); String inputLine; while ((inputLine = in.readLine()) != null) { System.out.println(inputLine); } in.close(); } } class SimpleX509TrustManager implements X509TrustManager { public void checkClientTrusted( X509Certificate[] cert, String s) throws CertificateException { } public void checkServerTrusted( X509Certificate[] cert, String s) throws CertificateException { } @Override public X509Certificate[] getAcceptedIssuers() { // TODO Auto-generated method stub return null; } } 
+6
source

All Articles