繁体   English   中英

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

[英]HttpClient javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated when time shifted?

由于要求,我们需要通过将系统日期转移到未来日期(如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与SSL

如上所述:

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

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

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

可以使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();
    }
}

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

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;  
    }  
}  

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

阅读了很多相关内容之后, 这就是帮助我的人

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

编辑文件: $JAVA_HOME/jre/lib/security/java.security

将这两个算法添加到列表DHE, ECDHE是将它们附加到jdk.tls.disabledAlgorithms

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

jdk.tls.disabledAlgorithms=SSLv3, DHE, ECDHE

就我而言,在以下场景中:

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

以下参数有效:

-Djdk.tls.client.protocols=TLSv1

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM