Javax.net.ssl.SSLPeerUnverifiedException: имя хоста не соответствует теме сертификата, предоставленной партнером
Я слежу за многими ссылками на stackoverflow и пробовал много решений, но ни один из них не работал у меня. Я использую WSO2 API manager
версию 1.9.1
. Я столкнулся с следующей ошибкой:
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)
Я разработал следующий код Java. Пожалуйста, помогите мне, что здесь не так. Мне нужно подключить небезопасный способ и разрешить подключения к сайтам SSL без сертификатов.
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);
}
Ответы
Ответ 1
Я потратил час, пытаясь исправить ту же проблему. Это то, что я придумал:
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();
Надеюсь, он работает и не использует устаревший код (httpclient 4.4.1).
Ответ 2
Замените это
CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf)
.setConnectionManager(cm).build();
с
CloseableHttpClient httpclient = HttpClients.custom()
.setSSLSocketFactory(sslsf)
.setConnectionManager(cm)
.setHostnameVerifier(SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER)
.build();
Если сертификат не подписан (даже самоподписанным), вы можете сделать
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;
}
}
Тогда
builder.loadTrustMaterial(new TrustAllStrategy());
EDIT: этот
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
sslcontext, //for you this is builder.build()
SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER
);
Ответ 3
Вот что я придумал:
SSLContextBuilder sslcontext = new SSLContextBuilder();
sslcontext.loadTrustMaterial(null, new TrustSelfSignedStrategy());
httpclient = HttpAsyncClients.custom().setSSLContext(sslcontext.build()).setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
.build();
Ответ 4
Благодаря всем решениям. Я пробовал все доступные решения через 1,5 дня и, наконец, теперь работал. Вот рабочий код
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);
Ответ 5
Попробовав большую часть решения, предложенного на этой странице, и другие связанные с ним обсуждения с использованием stackoverflow, я обнаружил, что ответ AJC выше работает с apache httpclient версии 4.5.
Причина:
При создании SSLConnectionSocketFactory, если HostVerifier не указан в конструкторе, он не устанавливается и используется DefaultHostVerifier. Таким образом, линия 3 решения AJC делает разницу.
(По крайней мере, это поведение в apache httpclient 4.5.3)