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

49,358

Solution 1

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:

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.

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

Solution 3

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

Solution 4

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

I solved my problem by ignoring some TLS algorithms.

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

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

So the end result, in my case, was:

jdk.tls.disabledAlgorithms=SSLv3, DHE, ECDHE

Share:
49,358

Related videos on Youtube

Liping Huang
Author by

Liping Huang

I'm Senior Java Developer with big experience and solid background in analysis, design, development and implementation of Java applications on Java platform using development environment, object-oriented development, design and programming. From my interests that I'm doing currently are Java, Spring, JPA/Hibernate, JEE, etc. These skills I'm using most of the time during development. You can contact me - liping.huang AT live.com

Updated on September 21, 2020

Comments

  • Liping Huang
    Liping Huang about 3 years

    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

    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

    as mentioned:

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

    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?

  • Sudip7
    Sudip7 about 9 years
    httpClient = HttpClientBuilder.create() .setSSLSocketFactory(socketFactory).build();. I am getting some error here. Error is: Exception in thread "main" java.lang.NoSuchFieldError: INSTANCE
  • Sudip7
    Sudip7 about 9 years
    <pre><code>at org.apache.http.impl.io.DefaultHttpRequestWriterFactory.<ini‌​t>(DefaultHttpReques‌​tWriterFactory.java:‌​52) at org.apache.http.impl.io.DefaultHttpRequestWriterFactory.<ini‌​t>(DefaultHttpReques‌​tWriterFactory.java:‌​56) at org.apache.http.impl.io.DefaultHttpRequestWriterFactory.<cli‌​nit>(DefaultHttpRequ‌​estWriterFactory.jav‌​a:46) at org.apache.http.impl.conn.ManagedHttpClientConnectionFactory‌​.<init>(ManagedHttpC‌​lientConnectionFacto‌​ry.java:72) at org.apache.http.impl.conn.ManagedHttpClientConnectionFactory‌​.<init>(ManagedHttpC‌​lientConnectionFacto‌​ry.java:84)</code></‌​pre>
  • abarisone
    abarisone over 8 years
    Could you elaborate more your answer adding a little more description about the solution you provide?
  • dominik
    dominik over 8 years
    For HttpClient 3.x instead of SSLConnectionSocketFactory(sslContext,SSLConnectionSocketFac‌​tory.ALLOW_ALL_HOSTN‌​AME_VERIFIER) use org.jsslutils.extra.apachehttpclient.SslContextedSecureProto‌​colSocketFactory(ssl‌​Context, false)
  • Klemens Zleptnig
    Klemens Zleptnig almost 5 years
    I had to use SSLContext ctx = SSLContext.getInstance("TLSv1.2"); (instead of "SSL").