HttpClient javax.net.ssl.SSLPeerUnverifiedException:peer在时移时未经过身份验证?

时间:2014-07-15 07:37:40

标签: java httpclient apache-httpclient-4.x

由于要求,我们需要通过将系统日期转移到未来日期(如2025-05-05)来测试https连接,问题是当使用HttpClient(版本4.2)时,会遇到异常 javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated

简单的代码段如下:

@Test
public void httpsShouldWorking() throws Exception {

    HttpClient client = new DefaultHttpClient();

    String urlOverHttps = "https://URL";
    HttpGet getMethod = new HttpGet(urlOverHttps);
    HttpResponse response = client.execute(getMethod);

    assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
}

我也谷歌搜索并找到了解决方案HttpClient with SSL

如上所述:

  

现在让我们将http客户端配置为信任所有证书链,无论其有效性如何:

但是在尝试之后,它无法正常工作并仍然获得auth异常。

在转移系统日期时是否有避免身份验证的解决方案?

5 个答案:

答案 0 :(得分:6)

可以使HttpClient绕过SSL证书有效性检查。此代码可用于获取HttpClient的实例:

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
......
private static HttpClient getHttpClient() {

    try {
        SSLContext sslContext = SSLContext.getInstance("SSL");

        sslContext.init(null,
                new TrustManager[]{new X509TrustManager() {
                    public X509Certificate[] getAcceptedIssuers() {

                        return null;
                    }

                    public void checkClientTrusted(
                            X509Certificate[] certs, String authType) {

                    }

                    public void checkServerTrusted(
                            X509Certificate[] certs, String authType) {

                    }
                }}, new SecureRandom());

        SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext,SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);



        HttpClient httpClient = HttpClientBuilder.create().setSSLSocketFactory(socketFactory).build();

        return httpClient;

    } catch (Exception e) {
        e.printStackTrace();
        return HttpClientBuilder.create().build();
    }
}

将不再抛出异常,当认证过期时,浏览器将发出有关过期证书的警告并让用户确认。

答案 1 :(得分:2)

public static HttpClient verifiedClient(HttpClient base) {  
    try {  
        SSLContext ctx = SSLContext.getInstance("SSL");  
        X509TrustManager tm = new X509TrustManager() {
            public java.security.cert.X509Certificate[] getAcceptedIssuers() {  
                return null;  
            }  
            @Override  
            public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}  
            @Override  
            public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}  
        };

        ctx.init(null, new TrustManager[] { tm }, null); 
        SSLSocketFactory ssf = new SSLSocketFactory(ctx, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); 
        ClientConnectionManager mgr = base.getConnectionManager();
        SchemeRegistry registry = mgr.getSchemeRegistry(); 
        registry.register(new Scheme("https", 443, ssf)); 
        return new DefaultHttpClient(mgr, base.getParams());  
    } catch (Exception ex) {  
        ex.printStackTrace();  
        return null;  
    }  
}  

答案 2 :(得分:2)

不是禁用整个安全链,而是将特定证书导入JAVA安装的密钥库更好。如何做到这一点,你可以在这里找到:http://java67.blogspot.co.at/2012/09/keytool-command-examples-java-add-view-certificate-ssl.html

答案 3 :(得分:1)

阅读了很多asnwers,this was the one that helped me

我通过忽略一些TLS算法解决了我的问题。

修改档案:$JAVA_HOME/jre/lib/security/java.security

将这两个算法添加到DHE, ECDHE列表中,将其添加到jdk.tls.disabledAlgorithms列表中。

因此,在我的情况下,最终结果是:

jdk.tls.disabledAlgorithms=SSLv3, DHE, ECDHE

答案 4 :(得分:0)

就我而言,在以下情况中:

  • JDK8
  • 从Junit测试运行
  • 使用resteasy-client

以下参数有效:

-Djdk.tls.client.protocols=TLSv1

有关更多信息,请查看:
https://www.java.com/en/configure_crypto.html