【问题标题】:HttpUnit WebConversation SSL IssuesHttpUnit WebConversation SSL 问题
【发布时间】:2011-06-19 14:42:23
【问题描述】:

如何从 WebConversationWebRequest 对象的上下文中忽略 SSL 证书问题?我知道我可以创建一个接受所有证书的假 TrustManager,但是如何在 HttpUnit 上下文中设置它?

这是我得到的例外:

[Security:090508]Certificate chain received from my.domain.com - NUM.NUM.NUM.NUM was incomplete., 
[Security:090477]Certificate chain received from my.domain.com - NUM.NUM.NUM.NUM was not trusted causing SSL handshake failure. 

我需要以某种方式将 SSLSocket 设置设置为 WebConversation 或 WebRequest 对象;查看 HttpUnit 的 JavaDocs 没有这样的方法或构造函数可以这样做。有没有办法可以将它包装在一些暴露了 SSLSocket 属性的对象中?

【问题讨论】:

    标签: java ssl https http-unit


    【解决方案1】:

    对我有用的是使用this tool 将服务器的无效证书添加到新的密钥库(创建一个文件 jssecacerts),然后用新的密钥库替换我现有的密钥库。
    cp cacerts cacerts.bak cp ~/tools/jssecacerts cacerts

    HttpUnit 在那之后工作得很好。

    【讨论】:

      【解决方案2】:

      根据this FAQ entry 看来,HttpUnit 使用的是Java 标准库提供的SSL 实现。编写和安装“全部接受”TrustManager 很简单:

      private static class AnyTrustManager implements X509TrustManager
      {
          public void checkClientTrusted(X509Certificate[] chain, String authType)
          {
          }
      
          public void checkServerTrusted(X509Certificate[] chain, String authType)
          {
          }
      
          public X509Certificate[] getAcceptedIssuers()
          {
              return new X509Certificate[0];
          }
      }
      
      static {
          try {
              SSLContext ssl = SSLContext.getInstance("SSL");
              ssl.init(null, new X509TrustManager[] {new AnyTrustManager()}, null);
              HttpsURLConnection.setDefaultSSLSocketFactory(ssl.getSocketFactory());
          } catch (NoSuchAlgorithmException ex) {
              throw new Error(ex);
          } catch (KeyManagementException ex) {
              throw new Error(ex);
          }
      }
      

      但是您应该记住,此代码示例可能需要一些修改才能与 HttpUnit 一起使用(例如,如果库使用自定义 SocketFactory 建立连接)

      由于 HttpUnit 似乎没有提供任何 API 来设置自定义 SSLSocketFactry,因此这里是设置默认 SSL 上下文的替代解决方案(仅限 Java 6)

      static {
          try {
              SSLContext ssl = SSLContext.getDefault();
              ssl.init(null, new X509TrustManager[] {new AnyTrustManager()}, null);
          } catch (NoSuchAlgorithmException ex) {
              throw new Error(ex);
          } catch (KeyManagementException ex) {
              throw new Error(ex);
          }
      }
      

      【讨论】:

      • 谢谢,标准的 WebConversation.getResponse() 调用会实现这个 TrustManager 吗?
      • 我认为需要进行测试。如问题中所述,可能需要设置默认 SSLFactory。我编辑我的回复以提供另一种解决方案/解决方法。
      • java.security.KeyManagementException: 默认 SSLContext 自动初始化
      • @Jcs 设置新的默认 SSLContext 不适用于 Java 8,而且会引发 Roger 发布的异常。您是否有更新以使其正常工作?
      【解决方案3】:

      如果您有权访问 WebClient,则可以这样做以跳过 SSL 证书验证:

      WebClient client = new WebClient();
      client.getOptions().setUseInsecureSSL(true);
      

      【讨论】:

        【解决方案4】:

        有点晚了,我只是遇到了这个问题,但我设法让httpunit 1.7.2AnyTrustManager 一起工作,按照Jsc 的回答,使用以下代码(httpunit 在后台使用HttpsURLConnectionOldImpl) :

        static {
            try {
                SSLContext ssl = SSLContext.getInstance("TLS");
                ssl.init(null, new X509TrustManager[] {new AnyTrustManager()}, null);
                com.sun.net.ssl.internal.www.protocol.https.HttpsURLConnectionOldImpl.setDefaultSSLSocketFactory(ssl.getSocketFactory());            
            } catch (NoSuchAlgorithmException ex) {
                throw new Error(ex);
            } catch (KeyManagementException ex) {
                throw new Error(ex);
            }
        }
        

        【讨论】:

          【解决方案5】:

          截至 2019 年,在 mac 上使用 oracle 8 jvm 和 httpunit 1.7,Jcs 8 年前的答案仍然非常接近,只需要多一行。

              // trust anything.
              static void setupSSL() {
                  if(sslSetupDone) {
                      return;
                  }
                  // System.setProperty("javax.net.debug", "ssl");
          
                  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 = null;
                  try {
                      sc = SSLContext.getInstance("TLS");  // formerly "ssl"
                      sc.init(null, trustAllCerts, null);
                      SSLContext.setDefault(sc);  //<====== one more line needed 
                  } catch (Exception e) {
                      e.printStackTrace(System.out);
                  }
                  HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
          
                  javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
                      public boolean verify(String urlHostname, SSLSession sslSession) {
                          return true;
                      }
                  });
          
                  sslSetupDone = true;
              }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2016-08-13
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-09-24
            相关资源
            最近更新 更多