HttpClient javax.net.ssl.SSLPeerUnverifiedException:时移时对等方未通过身份验证?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24752485/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 14:41:28  来源:igfitidea点击:

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

javahttpclientapache-httpclient-4.x

提问by Liping Huang

Due to the requirement, we need test the https connection by shift the system date to a future date like 2025-05-05, the problem is when using the HttpClient(version 4.2), will encounter the exception javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated

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

The simple code segment as below:

简单的代码段如下:

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

Also I google it and found a solution HttpClient with SSL

我也谷歌它并找到了一个解决方案HttpClient with SSL

as mentioned:

如前所述:

Let's now configure the http client to trust all certificate chains regardless of their validity:

现在让我们将 http 客户端配置为信任所有证书链,而不管它们的有效性:

But after the try, it is not working and still get the auth exception.

但是在尝试之后,它不起作用并且仍然得到身份验证异常。

Is there a solution to avoid the auth when shift the system date?

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

采纳答案by Liping Huang

It is possible to make HttpClient get around the checks of SSL certificate validity. This code can be used to obtain an instance of HttpClient:

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

The exception will no longer be thrown, when the certification is expired, the browser will issues a warning about an expired certificate and let user confirm.

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

回答by sunsys

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

回答by OASE Software GmbH

Instead of disabling the entire Security-Chain it would be much better to import a specific certificate to the keystore of your JAVA installation. How to do this, you can find out here: http://java67.blogspot.co.at/2012/09/keytool-command-examples-java-add-view-certificate-ssl.html

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

回答by Renann

After reading a lot of asnwers, this was the one that helped me.

在阅读了很多答案后,这是帮助我的一个

I solved my problem by ignoring some TLS algorithms.

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

Edit file: $JAVA_HOME/jre/lib/security/java.security

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

Add these two algorithms in the list DHE, ECDHEby appending them to the jdk.tls.disabledAlgorithms.

通过将这两个算法DHE, ECDHE附加到jdk.tls.disabledAlgorithms.

So the end result, in my case, was:

因此,就我而言,最终结果是:

jdk.tls.disabledAlgorithms=SSLv3, DHE, ECDHE

jdk.tls.disabledAlgorithms=SSLv3, DHE, ECDHE

回答by RicardoS

In my case, on the following scenario:

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

  • JDK8
  • Running from a Junit test
  • Using resteasy-client
  • JDK8
  • 从 Junit 测试运行
  • 使用resteasy客户端

The following parameter worked:

以下参数有效:

-Djdk.tls.client.protocols=TLSv1

For more information, take a look at:
https://www.java.com/en/configure_crypto.html

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