如何绕过Java Web服务客户端中的证书检查

使用案例:有一个Web服务发布为https:// abcd / zz?wsdl

我想要做的是查询这个URI,如果我得到一个VALID WSDL,我返回一个布尔值“true”否则为“false”。现在,如果我通过Chrome浏览器访问此URL,我将不得不手动接受关于证书警告,然后下载WSDL。但是如何通过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(); } } 

我收到一个错误:

线程“main”中的exceptionjavax.net.ssl.SSLHandshakeException:java.security.cert.CertificateException:在com.sun.net.ssl.internal.ssl.Alerts.getSSLException中找不到与IP地址abcd匹配的主题备用名称(未知来源) )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。在com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(未知来源)的com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(未知来源)的internal.ssl.Handshaker.fatalSE(未知来源) )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。 com.sun.net.ssl.internal.ssl.S.SLSLSI上的com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(未知来源)的internal.ssl.SSLSocketImpl.readRecord(未知来源).SLSLSI.Eart.SandHke.Shans(未知来源) )在com.sun.net.ssl .internal.ssl.SSLSocketImpl.startHandshake(未知来源)at sun.net.www.protocol.https.HttpsClient.afterConnect(未知来源)at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)at sun位于JavaHttpsExample.main(JavaHttpsExample.java:14)的sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(未知来源)的.net.www.protocol.http.HttpURLConnection.getInputStream(未知来源)引起:java。 security.cert.CertificateException:在com.sun.net上的sun.security.util.HostnameChecker.match(未知来源)的sun.security.util.HostnameChecker.matchIP(未知来源)中找不到与IP地址abcd匹配的主题备用名称。 com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(未知来源)中的ssl.internal.ssl.X509TrustManagerImpl.checkIdentity(未知来源)

我用abcd取代了真正的IP(当然)

不要使用存根的TrustManager,因为这会使您的应用程序信任所有人 。 我建议下载该站点提供的证书并将其添加到私有的可信密钥库。 这样,您就可以为该网站制作例外,而无需对所有人进行绿化。

我也喜欢这种方法,因为它不需要更改代码。

在Chrome中,点击url左侧的锁定图标。 然后单击“证书信息”。 转到“详细信息”选项卡,然后单击“复制到文件”。 将其保存为“base64编码的X.509(.cer)”到“SITENAME.cer”。

将$ JAVA_HOME / lib / security / cacerts复制到应用程序的目录“mykeystore.jks”。

安装证书:

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

现在,当您运行应用程序时,请告诉它使用私有证书存储:

 java -Djavax.net.ssl.trustStore=mykeystore.jks ... 

只需实现您自己的信任管理器,如下面的代码所示

 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; } }