3

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?

Aruna
  • 11,959
  • 3
  • 28
  • 42
Liping Huang
  • 4,378
  • 4
  • 29
  • 46

5 Answers5

6

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.

Liping Huang
  • 4,378
  • 4
  • 29
  • 46
  • httpClient = HttpClientBuilder.create() .setSSLSocketFactory(socketFactory).build();. I am getting some error here. Error is: Exception in thread "main" java.lang.NoSuchFieldError: INSTANCE – Sudip7 Nov 11 '14 at 09:53
  • at org.apache.http.impl.io.DefaultHttpRequestWriterFactory.(DefaultHttpRequestWriterFactory.java:52) at org.apache.http.impl.io.DefaultHttpRequestWriterFactory.(DefaultHttpRequestWriterFactory.java:56) at org.apache.http.impl.io.DefaultHttpRequestWriterFactory.(DefaultHttpRequestWriterFactory.java:46) at org.apache.http.impl.conn.ManagedHttpClientConnectionFactory.(ManagedHttpClientConnectionFactory.java:72) at org.apache.http.impl.conn.ManagedHttpClientConnectionFactory.(ManagedHttpClientConnectionFactory.java:84) – Sudip7 Nov 11 '14 at 09:59
  • For HttpClient 3.x instead of `SSLConnectionSocketFactory(sslContext,SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER)` use `org.jsslutils.extra.apachehttpclient.SslContextedSecureProtocolSocketFactory(sslContext, false)` – dominik Jul 27 '15 at 09:19
3
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;  
    }  
}  
sunsys
  • 31
  • 1
2

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

OASE Software GmbH
  • 152
  • 1
  • 3
  • 11
2

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

Community
  • 1
  • 1
Renann
  • 552
  • 1
  • 7
  • 12
0

In my case, on the following scenario:

  • JDK8
  • Running from a Junit test
  • Using resteasy-client

The following parameter worked:

-Djdk.tls.client.protocols=TLSv1

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

RicardoS
  • 2,088
  • 1
  • 21
  • 22