javax.net.ssl.SSLPeerUnverifiedException: Host name does not match the certificate subject provided by the peer
Solution 1
I have spent an hour trying to fix the same issue. This is what I come up with:
final SSLConnectionSocketFactory sslsf;
try {
sslsf = new SSLConnectionSocketFactory(SSLContext.getDefault(),
NoopHostnameVerifier.INSTANCE);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
final Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", new PlainConnectionSocketFactory())
.register("https", sslsf)
.build();
final PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry);
cm.setMaxTotal(100);
httpClient = HttpClients.custom()
.setSSLSocketFactory(sslsf)
.setConnectionManager(cm)
.build();
Hopefully, it works and does not use any deprecated code (httpclient 4.4.1).
Solution 2
Replace this
CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf)
.setConnectionManager(cm).build();
with
CloseableHttpClient httpclient = HttpClients.custom()
.setSSLSocketFactory(sslsf)
.setConnectionManager(cm)
.setHostnameVerifier(SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER)
.build();
If the certificate isn't signed (not even self-signed), then you can do
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
public class TrustAllStrategy implements TrustStrategy {
@Override
public boolean isTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
return true;
}
}
Then
builder.loadTrustMaterial(new TrustAllStrategy());
EDIT: this
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
sslcontext, //for you this is builder.build()
SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER
);
Solution 3
Thanks to all the solutions. I have been trying all the solutions available online for 1.5 days now and finally it worked now. Here is the working code
SSLContextBuilder builder = new SSLContextBuilder();
builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(builder.build(), NoopHostnameVerifier.INSTANCE);
Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", new PlainConnectionSocketFactory())
.register("https", sslConnectionSocketFactory)
.build();
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry);
cm.setMaxTotal(100);
CloseableHttpClient httpclient = HttpClients.custom()
.setSSLSocketFactory(sslConnectionSocketFactory)
.setConnectionManager(cm)
.build();
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(postEntity);
httpPost.expectContinue();
CloseableHttpResponse response = httpclient.execute(httpPost);
Solution 4
This is what I came up with:
SSLContextBuilder sslcontext = new SSLContextBuilder();
sslcontext.loadTrustMaterial(null, new TrustSelfSignedStrategy());
httpclient = HttpAsyncClients.custom().setSSLContext(sslcontext.build()).setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
.build();
Solution 5
After trying most of the solution suggested on this page and other related stackoverflow discussions, I found AJC's response above works with apache httpclient version 4.5.
Reason: While creating SSLConnectionSocketFactory if the HostVerifier is not specified in the constructor, it does not get set and the DefaultHostVerifier is used. So line 3 of AJC's solutionmakes the difference.
(Atleast this is the behavior in apache httpclient 4.5.3 )
Admin
Updated on March 18, 2020Comments
-
Admin about 4 years
I follow many links on stackoverflow and tried many solutions, but none of them worked for me. I'm using
WSO2 API manager
version1.9.1
. I am facing following error:Exception in thread "main" javax.net.ssl.SSLPeerUnverifiedException: Host name 'XXXXXXXXX' does not match the certificate subject provided by the peer (CN=localhost, O=WSO2, L=Mountain View, ST=CA, C=US) at org.apache.http.conn.ssl.SSLConnectionSocketFactory.verifyHostname(SSLConnectionSocketFactory.java:465) at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:395) at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:353) at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:134) at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:353) at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:380) at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236) at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184) at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88) at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110) at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184) at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82) at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:107) at com.java.pushNotifications.WSO2DemoClient.main(WSO2DemoClient.java:49)
I developed the following Java code. Please help me what's going wrong here. I need to connect insecure way and allow connections to SSL sites without certs.
public static void main(String[] args) throws ClientProtocolException, IOException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException { SSLContextBuilder builder = new SSLContextBuilder(); builder.loadTrustMaterial(null, new TrustSelfSignedStrategy()); SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(builder.build()); Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create() .register("http", new PlainConnectionSocketFactory()) .register("https", sslsf) .build(); PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry); cm.setMaxTotal(2000);//max connection CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf) .setConnectionManager(cm).build(); HttpGet httpGet = new HttpGet("https://XXXXXXXXXX:8243/token"); CloseableHttpResponse response = httpclient.execute(httpGet); String json =" {\"data\":\"grant_type=password&username=test&password=test123\"}"; try { HttpPost httpost = new HttpPost(url); httpost.setHeader("Content-Type", "application/x-www-form-urlencoded"); httpost.setHeader("Authorization", "Basic XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"); httpost.setEntity(new StringEntity(json)); HttpResponse httpResponse = httpclient.execute(httpost); System.out.println(httpResponse.getStatusLine()); } finally { response.close(); } String responseString1 = new BasicResponseHandler().handleResponse(response); System.out.println("Response : "+responseString1); }