忽略Java中的SSL验证

前端之家收集整理的这篇文章主要介绍了忽略Java中的SSL验证前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我必须使用无效的SSL证书调用托管在Web服务器上的HTTP服务.在dev中,我使用keytool导入证书,但每个客户端安装证书都不同,所以我不能捆绑它.

前言:我知道跳过SSL验证真的很丑陋.在这种具体情况下,我甚至不需要SSL,系统中的所有其他通信都是通过简单的HTTP.所以我真的不在乎MITM攻击等等.攻击者不需要去破坏SSL,因为数据没有SSL.这是对我无法控制的遗留系统的支持.

我正在使用具有NaiveTrustManager和NaiveHostnameVerifier的SSLSocketFactory的HttpURLConnection.这适用于我尝试的一些自签名服务器,但不在客户的网站上.我得到的错误是:

  1. javax.net.ssl.SSLKeyException: [Security:090477]Certificate chain received from xxxxxxxxxx was not trusted causing SSL handshake failure.
  2. at com.certicom.tls.interfaceimpl.TLSConnectionImpl.fireException(Unknown Source)
  3. at com.certicom.tls.interfaceimpl.TLSConnectionImpl.fireAlertSent(Unknown Source)
  4. at com.certicom.tls.record.handshake.HandshakeHandler.fireAlert(Unknown Source)
  5. at com.certicom.tls.record.handshake.HandshakeHandler.fireAlert(Unknown Source)
  6. at com.certicom.tls.record.handshake.ClientStateReceivedServerHello.handle(Unknown Source)
  7. at com.certicom.tls.record.handshake.HandshakeHandler.handleHandshakeMessage(Unknown Source)
  8. at com.certicom.tls.record.handshake.HandshakeHandler.handleHandshakeMessages(Unknown Source)
  9. at com.certicom.tls.record.MessageInterpreter.interpretContent(Unknown Source)
  10. at com.certicom.tls.record.MessageInterpreter.decryptMessage(Unknown Source)
  11. at com.certicom.tls.record.ReadHandler.processRecord(Unknown Source)
  12. at com.certicom.tls.record.ReadHandler.readRecord(Unknown Source)
  13. at com.certicom.tls.record.ReadHandler.readUntilHandshakeComplete(Unknown Source)
  14. at com.certicom.tls.interfaceimpl.TLSConnectionImpl.completeHandshake(Unknown Source)
  15. at com.certicom.tls.record.WriteHandler.write(Unknown Source)
  16. at com.certicom.io.OutputSSLIOStreamWrapper.write(Unknown Source)
  17. at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:65)
  18. at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:123)
  19. at java.io.FilterOutputStream.flush(FilterOutputStream.java:123)
  20. at weblogic.net.http.HttpURLConnection.writeRequests(HttpURLConnection.java:154)
  21. at weblogic.net.http.HttpURLConnection.getInputStream(HttpURLConnection.java:358)
  22. at weblogic.net.http.SOAPHttpsURLConnection.getInputStream(SOAPHttpsURLConnection.java:37)
  23. at weblogic.net.http.HttpURLConnection.getResponseCode(HttpURLConnection.java:947)
  24. at (my own code)

我的SimpleSocketFactory看起来像:

  1. public static final SSLSocketFactory getSocketFactory()
  2. {
  3. if ( sslSocketFactory == null ) {
  4. try {
  5. // get ssl context
  6. SSLContext sc = SSLContext.getInstance("SSL");
  7.  
  8. // Create a trust manager that does not validate certificate chains
  9. TrustManager[] trustAllCerts = new TrustManager[]{
  10. new NaiveTrustManager() {
  11. public java.security.cert.X509Certificate[] getAcceptedIssuers() {
  12. log.debug("getAcceptedIssuers");
  13. return new java.security.cert.X509Certificate[0];
  14. }
  15. public void checkClientTrusted(
  16. java.security.cert.X509Certificate[] certs,String authType) {
  17. log.debug("checkClientTrusted");
  18. }
  19. public void checkServerTrusted(
  20. java.security.cert.X509Certificate[] certs,String authType) {
  21. log.debug("checkServerTrusted");
  22. }
  23. }
  24. };
  25.  
  26. sc.init(null,trustAllCerts,new java.security.SecureRandom());
  27. // EDIT: fixed the following line that was redeclaring SSLSocketFactory sslSocketFactory,returning null every time. Same result though.
  28. sslSocketFactory = sc.getSocketFactory();
  29.  
  30. HttpsURLConnection.setDefaultSSLSocketFactory(sslSocketFactory);
  31. // EDIT: The following line has no effect
  32. //HttpsURLConnection.setDefaultHostnameVerifier(new NaiveHostNameVerifier());
  33.  
  34. } catch (KeyManagementException e) {
  35. log.error ("No SSL algorithm support: " + e.getMessage(),e);
  36. } catch (NoSuchAlgorithmException e) {
  37. log.error ("Exception when setting up the Naive key management.",e);
  38. }
  39. }
  40. return sslSocketFactory;
  41. }

NaiveHostnameVerifier有一种方法来限制有效的主机,但它是空的,所以基本上接受任何东西:

  1. public class NaiveHostnameVerifier implements HostnameVerifier {
  2. String[] patterns;
  3.  
  4. public NaiveHostnameVerifier () {
  5. this.patterns=null;
  6. }
  7.  
  8. public NaiveHostnameVerifier (String[] patterns) {
  9. this.patterns = patterns;
  10. }
  11.  
  12. public boolean verify(String urlHostName,SSLSession session) {
  13. if (patterns==null || patterns.length==0) {
  14. return true;
  15. } else {
  16. for (String pattern : patterns) {
  17. if (urlHostName.matches(pattern)) {
  18. return true;
  19. }
  20. }
  21. return false;
  22. }
  23. }
  24. }

用法是这样的:

  1. try {
  2. conn = (HttpURLConnection)url.openConnection();
  3. if (conn instanceof HttpsURLConnection) {
  4. ((HttpsURLConnection)conn).setSSLSocketFactory(SimpleSSLSocketFactory.getSocketFactory());
  5. // EDIT: added this line,the HV has to be set on connection,not on the factory.
  6. ((HttpsURLConnection)conn).setHostnameVerifier(new NaiveHostnameVerifier());
  7. }
  8. conn.setDoInput(true);
  9. conn.setDoOutput(true);
  10. conn.setRequestMethod("POST");
  11. conn.setRequestProperty("Content-type","application/x-www-form-urlencoded");
  12. conn.connect();
  13.  
  14. StringBuffer sbContent = new StringBuffer();
  15. // (snip)
  16. DataOutputStream stream = new DataOutputStream(conn.getOutputStream ());
  17. stream.writeBytes(sbContent.toString());
  18. stream.flush();
  19. stream.close();
  20. } catch (ClassCastException e) {
  21. log.error("The URL does not seem to point to a HTTP connection");
  22. return null;
  23. } catch (IOException e) {
  24. log.error("Error accessing the requested URL",e);
  25. return null;
  26. }

当我正在搜索错误消息时,大多数人只是在他们的商店导入证书,但再次,我不能这样做,因为我不知道哪个证书是.我唯一的选择,如果这不工作是制作一个工具,可以下载证书,并添加一个更简单的方式,隐藏的命令行,但我宁愿让我的Java代码只是忽略无效的证书.

任何想法 ?

解决方法

上面的代码实际上没有错误.这个问题似乎在于Weblogic和这个Certicom TLS模块.当我查看服务器选项时,SSL和Advanced我看到我可以指定一个自定义的HostnameVerifier(SSLMBean.HostnameVerifier),但建议有能力干扰证书验证的唯一元素已被弃用.

我在Weblogic之外尝试了上面的代码,它工作得很好(固定了Postname中的HostnameVerifier).

然后,我试图在this other question中提出由ipolevoy提出的“-DUseSunHttpHandler = true”到Weblogic参数.它开始工作.

话虽如此,在Oracle Service Bus服务器上切换HTTP处理程序似乎有点冒险.几个星期的时间里,可能会有副作用让我再次咬我

我还试图定义我自己的trustStore,并将其指向包含所需密钥的jssecacert. Weblogic也被忽略,因为它有自己的每个服务器的trustStore设置.所以我要求管理员手动导入所需的键或将Weblogic指向我自己的商店.

猜你在找的Java相关文章