Java HttpUnit网络会话SSL问题

Java HttpUnit网络会话SSL问题,java,ssl,https,http-unit,Java,Ssl,Https,Http Unit,如何从WebConversation或WebRequest对象的上下文中忽略SSL证书问题?我知道我可以创建一个假的TrustManager,它接受所有证书,但是我如何在HttpUnit上下文中设置它呢 以下是我得到的一个例外: [Security:090508]Certificate chain received from my.domain.com - NUM.NUM.NUM.NUM was incomplete., [Security:090477]Certificate chain r

如何从
WebConversation
WebRequest
对象的上下文中忽略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对象;看看JavadocsforHttpUnit,没有这样的方法或构造函数可以做到这一点。有没有一种方法可以将其包装到某个已公开SSLSocket属性的对象中?

根据,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来设置自定义sslsocketfactory,因此这里有一个替代解决方案来设置默认SSL上下文(仅限Java 6)


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


之后,HttpUnit运行良好

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

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

稍微晚了一点,我才遇到这个问题,但我成功地使用了
httpunit 1.7.2
AnyTrustManager
,按照
Jsc
的回答,使用了以下代码(httpunit在后台使用
HttpsURLConnectionOldImpl
):


到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;
    }
//相信任何事。
静态void setupSSL(){
如果(sslSetupDone){
返回;
}
//setProperty(“javax.net.debug”、“ssl”);
TrustManager[]trustAllCerts=new TrustManager[]{new X509TrustManager(){
public java.security.cert.X509Certificate[]getAcceptedIssuers(){
返回null;
}
public void checkClientTrusted(X509Certificate[]证书,字符串authType){
}
public void checkServerTrusted(X509Certificate[]证书,字符串authType){
}
} };
SSLContext sc=null;
试一试{
sc=SSLContext.getInstance(“TLS”);//以前是“ssl”
sc.init(null,trustAllCerts,null);

SSLContext.setDefault(sc);//谢谢,标准的WebConversation.getResponse()也将如此调用实现此TrustManager?我认为需要进行测试。如问题中所述,可能需要设置默认SSLFactory。我编辑响应以提供另一个解决方案/workaround.java.security.KeyManagementException:默认SSLContext已初始化automatically@Jcs设置新的默认SSLContext不适用于Java 8和此外,罗杰正在发布一个异常。你是否有更新来让它工作?
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);
    }
}
    // 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;
    }