HttpClient javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated when time shifted?
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
Related videos on Youtube
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, 2020Comments
-
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 exceptionjavax.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 about 9 yearshttpClient = HttpClientBuilder.create() .setSSLSocketFactory(socketFactory).build();. I am getting some error here. Error is: Exception in thread "main" java.lang.NoSuchFieldError: INSTANCE
-
Sudip7 about 9 years<pre><code>at org.apache.http.impl.io.DefaultHttpRequestWriterFactory.<init>(DefaultHttpRequestWriterFactory.java:52) at org.apache.http.impl.io.DefaultHttpRequestWriterFactory.<init>(DefaultHttpRequestWriterFactory.java:56) at org.apache.http.impl.io.DefaultHttpRequestWriterFactory.<clinit>(DefaultHttpRequestWriterFactory.java:46) at org.apache.http.impl.conn.ManagedHttpClientConnectionFactory.<init>(ManagedHttpClientConnectionFactory.java:72) at org.apache.http.impl.conn.ManagedHttpClientConnectionFactory.<init>(ManagedHttpClientConnectionFactory.java:84)</code></pre>
-
abarisone over 8 yearsCould you elaborate more your answer adding a little more description about the solution you provide?
-
dominik over 8 yearsFor HttpClient 3.x instead of
SSLConnectionSocketFactory(sslContext,SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER)
useorg.jsslutils.extra.apachehttpclient.SslContextedSecureProtocolSocketFactory(sslContext, false)
-
Klemens Zleptnig almost 5 yearsI had to use
SSLContext ctx = SSLContext.getInstance("TLSv1.2");
(instead of "SSL").