如何绕过Java Web服务客户端中的证书检查 [英] How to bypass certificate checking in a Java web service client
问题描述
使用案例:
有一个网站服务发布为 https:// abcd / zz?wsdl
我想做的是查询这个URI,如果我得到一个VALID WSDL,我返回一个布尔true,否则为false。
现在,如果我通过Chrome浏览器访问此URL,我将不得不手动对cert警告进行接受,然后下载WSDL。但是如何通过Java / HttpsURLConnection进行此操作
What i would like to do is to query this URI and IF i get a VALID WSDL, i return a boolean "true" else "false. Now, if i go via Chrome browser to this URL, i would have to manually do an accept on the cert warning, and THEN the WSDL gets downloaded. But how can do this via 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://a.b.c.d/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();
}
}
我收到错误:
线程中的异常mainjavax.net.ssl.SSLHandshakeException:
java.security.cert.CertificateException:没有主题替代名称
匹配IP地址abcd,发现于
com.sun.net.ssl.internal.ssl.Alerts.getSSLException(未知来源)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal (未知来源)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown来源)
at
com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(Unknown
Source)at
com.sun.net.ssl.internal.ssl .ClientHandshaker.processMessage(未知
来源)at
com.sun.net.ssl.internal.ssl.Handshaker.processLoop(未知来源)
at com.sun.net.ssl.internal $。b $ b com.sun.net.ssl .ssl.Handshaker.process_record(未知
来源) .internal.ssl.SSLSocketImpl.readRecord(未知来源)
at
com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(未知
来源)at
com .sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(未知
来源)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
来源)
sun.net.www.protocol.http.HttpURLConnection.getInputStream(未知
来源)at
sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(Unknown $ b来自JavaHttpsExample.main的$ b Source(JavaHttpsExample.java:14)引起:
java.security.cert.CertificateException:没有主题替代名称
匹配在
sun找到的IP地址abcd。 security.util.HostnameChecker.matchIP(未知来源)
sun.security.util.HostnameChecker.match(未知来源)at
com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkIdentity(未知
来源)
com.sun .net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(未知
来源)
Exception in thread "main" javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative names matching IP address a.b.c.d found at 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.HttpsURLConnectionImpl.getInputStream(Unknown Source) at JavaHttpsExample.main(JavaHttpsExample.java:14) Caused by: java.security.cert.CertificateException: No subject alternative names matching IP address a.b.c.d found at sun.security.util.HostnameChecker.matchIP(Unknown Source) at sun.security.util.HostnameChecker.match(Unknown Source) at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkIdentity(Unknown Source) at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)
我已用实际IP替换abcd(当然)
i have replaced the real IP with a.b.c.d (of course)
推荐答案
不要使用存根的TrustManager,因为这会使您的应用程序信任 每个人的。我建议下载该站点提供的证书并将其添加到私有的可信密钥库。这可以让你为那个站点制作一个例外而不会给每个人带来绿灯。
Don't use a stubbed out TrustManager as this makes your application trust everyone. I would recommend downloading the certificate presented by the site and adding it to a private, trusted keystore. This lets you make an exception for that one site without greenlighting everyone.
我也喜欢这种方法,因为它不需要更改代码。
I also like this approach because it requires no code changes.
在Chrome中,点击网址左侧的锁定图标。然后单击证书信息。转到详细信息选项卡,然后单击复制到文件。将其保存为base64编码的X.509(.cer)到SITENAME.cer。
In Chrome, click the lock icon to the left of the url. Then click "Certificate Information". Go to the "Details" tab and click "Copy to file". Save it as a "base64 encoded X.509 (.cer)" to "SITENAME.cer".
将$ JAVA_HOME / lib / security / cacerts复制到应用程序的目录中asmykeystore.jks。
Copy $JAVA_HOME/lib/security/cacerts to your application's directory as "mykeystore.jks".
安装证书:
keytool -keystore mykeystore.jks -storepass changeit -importcert -alias SITENAME -trustcacerts -file SITE.cer
现在,当您运行应用程序时,请告诉它使用私有证书存储:
Now, when you run your application, tell it to use the private certificate store:
java -Djavax.net.ssl.trustStore=mykeystore.jks ...
这篇关于如何绕过Java Web服务客户端中的证书检查的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!