it-swarm.com.de

javax.net.ssl.SSLPeerUnverifiedException: Der Hostname stimmt nicht mit dem vom Peer angegebenen Zertifikatssubjekt überein

Ich verfolge viele Links zum Stackoverflow und habe viele Lösungen ausprobiert, aber keine davon hat für mich funktioniert. Ich benutze WSO2 API manager Ausführung 1.9.1. Ich stehe vor folgendem Fehler:

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)

Ich habe den folgenden Code entwickelt Java. Bitte helfen Sie mir, was hier falsch läuft. Ich muss auf unsichere Weise eine Verbindung herstellen und Verbindungen zu SSL-Sites ohne certs zulassen.

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);
    }
23
user5268786

Ich habe eine Stunde lang versucht, das gleiche Problem zu beheben. Das habe ich mir ausgedacht:

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();

Hoffentlich funktioniert es und verwendet keinen veralteten Code (httpclient 4.4.1).

41
antonpp

Ersetzen Sie diese

CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf)
            .setConnectionManager(cm).build();

mit

CloseableHttpClient httpclient = HttpClients.custom()
            .setSSLSocketFactory(sslsf)
            .setConnectionManager(cm)
            .setHostnameVerifier(SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER)
            .build();

Wenn das Zertifikat nicht signiert ist (auch nicht selbst signiert), können Sie dies tun

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

Dann

builder.loadTrustMaterial(new TrustAllStrategy());

EDIT: das

SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
            sslcontext, //for you this is builder.build()
            SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER
);
15
EpicPandaForce

Vielen Dank an alle Lösungen. Ich habe jetzt 1,5 Tage lang alle online verfügbaren Lösungen ausprobiert und jetzt hat es endlich funktioniert. Hier ist der Arbeitscode

 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);
10
AJC

Das habe ich mir ausgedacht:

 SSLContextBuilder sslcontext = new SSLContextBuilder();
 sslcontext.loadTrustMaterial(null, new TrustSelfSignedStrategy());
 httpclient = HttpAsyncClients.custom().setSSLContext(sslcontext.build()).setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
      .build();
5
Dudi

Nachdem ich den größten Teil der auf dieser Seite vorgeschlagenen Lösung und andere verwandte Diskussionen über Stackoverflow ausprobiert hatte, stellte ich fest, dass die obige Antwort von AJC mit Apache httpclient Version 4.5 funktioniert.

Grund: Beim Erstellen von SSLConnectionSocketFactory wird der HostVerifier nicht festgelegt, wenn er nicht im Konstruktor angegeben ist, und der DefaultHostVerifier wird verwendet. Zeile 3 der AJC-Lösung macht also den Unterschied.

(Zumindest ist dies das Verhalten in Apache httpclient 4.5.3)

3
Ashutosh