it-swarm.com.de

Wie gehe ich mit Apache HttpClient mit ungültigen SSL-Zertifikaten um?

Ich weiß, es gibt viele verschiedene Fragen und so viele Antworten auf dieses Problem ... Aber ich kann nicht verstehen ...

Ich habe: ubuntu-9.10-desktop-AMD64 + NetBeans6.7.1 "as is" von off installiert. rep . Ich muss über HTTPS eine Verbindung zu einer Site herstellen. Dafür verwende ich den HttpClient von Apache.

Aus dem Tutorial habe ich gelesen:

"Wenn Sie JSSE korrekt installiert haben, sollte die sichere HTTP - Kommunikation über SSL wie folgt sein
So einfach wie die einfache HTTP-Kommunikation. "Und ein Beispiel:

HttpClient httpclient = new HttpClient();
GetMethod httpget = new GetMethod("https://www.verisign.com/"); 
try { 
  httpclient.executeMethod(httpget);
  System.out.println(httpget.getStatusLine());
} finally {
  httpget.releaseConnection();
}

Inzwischen schreibe ich das:

HttpClient client = new HttpClient();

HttpMethod get = new GetMethod("https://mms.nw.ru");
//get.setDoAuthentication(true);

try {
    int status = client.executeMethod(get);
    System.out.println(status);

    BufferedInputStream is = new BufferedInputStream(get.getResponseBodyAsStream());
    int r=0;byte[] buf = new byte[10];
    while((r = is.read(buf)) > 0) {
        System.out.write(buf,0,r);
    }

} catch(Exception ex) {
    ex.printStackTrace();
}

Als Ergebnis habe ich eine Reihe von Fehlern:

javax.net.ssl.SSLHandshakeException: Sun.security.validator.ValidatorException: PKIX path building failed: Sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
        at Sun.security.ssl.Alerts.getSSLException(Alerts.Java:192)
        at Sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.Java:1627)
        at Sun.security.ssl.Handshaker.fatalSE(Handshaker.Java:204)
        at Sun.security.ssl.Handshaker.fatalSE(Handshaker.Java:198)
        at Sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.Java:994)
        at Sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.Java:142)
        at Sun.security.ssl.Handshaker.processLoop(Handshaker.Java:533)
        at Sun.security.ssl.Handshaker.process_record(Handshaker.Java:471)
        at Sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.Java:904)
        at Sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.Java:1132)
        at Sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.Java:643)
        at Sun.security.ssl.AppOutputStream.write(AppOutputStream.Java:78)
        at Java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.Java:82)
        at Java.io.BufferedOutputStream.flush(BufferedOutputStream.Java:140)
        at org.Apache.commons.httpclient.HttpConnection.flushRequestOutputStream(HttpConnection.Java:828)
        at org.Apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodBase.Java:2116)
        at org.Apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.Java:1096)
        at org.Apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.Java:398)
        at org.Apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.Java:171)
        at org.Apache.commons.httpclient.HttpClient.executeMethod(HttpClient.Java:397)
        at org.Apache.commons.httpclient.HttpClient.executeMethod(HttpClient.Java:323)
        at simpleapachehttp.Main.main(Main.Java:41)
Caused by: Sun.security.validator.ValidatorException: PKIX path building failed: Sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
        at Sun.security.validator.PKIXValidator.doBuild(PKIXValidator.Java:302)
        at Sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.Java:205)
        at Sun.security.validator.Validator.validate(Validator.Java:235)
        at Sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.Java:147)
        at Sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.Java:230)
        at Sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.Java:270)
        at Sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.Java:973)
        ... 17 more
Caused by: Sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
        at Sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.Java:191)
        at Java.security.cert.CertPathBuilder.build(CertPathBuilder.Java:255)
        at Sun.security.validator.PKIXValidator.doBuild(PKIXValidator.Java:297)
        ... 23 more

Was muss ich tun, um eine einfachste SSL-Verbindung herzustellen? (Wahrscheinlich ohne KeyManager und Trust-Manager usw.).

113
rauch

https://mms.nw.ru verwendet ein selbstsigniertes Zertifikat, das offensichtlich nicht im Standardsatz von Vertrauensmanagern enthalten ist.

Sie müssen eine der folgenden Möglichkeiten haben:

  • Konfigurieren Sie den SSLContext mit einem TrustManager, der alle Zertifikate akzeptiert (siehe unten).

  • Konfigurieren Sie den SSLContext mit einem geeigneten Trust Store, der Ihr Zertifikat enthält

  • Fügen Sie das Zertifikat für diese Site dem Standard-Java-Truststore hinzu.

Hier ist ein Beispielprogramm, das einen (meistens wertlosen) SSL-Kontext erstellt, der alle Zertifikate akzeptiert:

import Java.net.URL;
import Java.security.SecureRandom;
import Java.security.cert.CertificateException;
import Java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

public class SSLTest {

    public static void main(String [] args) throws Exception {
        // configure the SSLContext with a TrustManager
        SSLContext ctx = SSLContext.getInstance("TLS");
        ctx.init(new KeyManager[0], new TrustManager[] {new DefaultTrustManager()}, new SecureRandom());
        SSLContext.setDefault(ctx);

        URL url = new URL("https://mms.nw.ru");
        HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
        conn.setHostnameVerifier(new HostnameVerifier() {
            @Override
            public boolean verify(String arg0, SSLSession arg1) {
                return true;
            }
        });
        System.out.println(conn.getResponseCode());
        conn.disconnect();
    }

    private static class DefaultTrustManager implements X509TrustManager {

        @Override
        public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}

        @Override
        public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }
    }
}
151
Kevin

https://mms.nw.ru verwendet wahrscheinlich ein Zertifikat, das nicht von einer Zertifizierungsstelle ausgestellt wurde. Infolgedessen müssen Sie das Zertifikat zu Ihrem vertrauenswürdigen Java-Schlüsselspeicher hinzufügen, wie in der gültige Zertifizierungspfad für das angeforderte Ziel nicht gefunden :

Bei der Arbeit an einem Client funktioniert das mit einem SSL-fähigen Server in https-Protokoll, könnten Sie Fehler .__ erhalten. 'konnte keine gültige Zertifizierung finden Pfad zum angeforderten Ziel 'wenn die Serverzertifikat wird nicht von .__ ausgestellt. Zertifizierungsstelle, aber eine selbst von einem privaten CMS signiert oder herausgegeben.

Keine Panik Alles was Sie tun müssen, ist zu Fügen Sie das Serverzertifikat Ihrem .__ hinzu. vertrauenswürdiger Java-Schlüsselspeicher, wenn Ihr Client ist in Java geschrieben. Du könntest sein Fragen, wie, als ob Sie nicht auf .__ zugreifen können. der Rechner, auf dem sich der Server befindet Eingerichtet. Es gibt ein einfaches Programm kann dir helfen. Bitte laden Sie die Java Programm und ausführen

% Java InstallCert _web_site_hostname_

Dieses Programm hat eine Verbindung zu .__ hergestellt. den angegebenen Host und startete ein SSL Handschlag Es wurde die Ausnahme gedruckt Stack-Trace des aufgetretenen Fehlers und zeigt Ihnen die von .__ verwendeten Zertifikate. der Server. Nun werden Sie aufgefordert, das .__ hinzuzufügen. Zertifikat an Ihren vertrauenswürdigen KeyStore.

Wenn Sie Ihre Meinung geändert haben, geben Sie .__ ein. 'q'. Wenn Sie wirklich die .__ hinzufügen möchten. Zertifikat, geben Sie '1' oder eine andere Nummern, um andere Zertifikate hinzuzufügen, sogar ein CA-Zertifikat, aber normalerweise will das nicht tun Sobald du hast Wenn Sie Ihre Wahl getroffen haben, wird das Programm Anzeige des vollständigen Zertifikats und fügte es dann einem Java-KeyStore mit dem Namen .__ hinzu. 'jssecacerts' im aktuellen Verzeichnis.

Um es in Ihrem Programm zu verwenden, entweder Konfigurieren Sie JSSE so, dass es als Vertrauensstellung verwendet wird speichern oder kopieren Sie es in Ihre $ Java_HOME/jre/lib/Sicherheitsverzeichnis . Wenn Sie möchten, dass alle Java-Anwendungen Erkennen Sie das Zertifikat als vertrauenswürdig und nicht nur JSSE, Sie könnten auch Überschreiben Sie die Cacerts-Datei in diesem Verzeichnis.

Nach all dem kann JSSE Handshake mit dem Host durchführen, die Sie überprüfen können, indem Sie die Programm erneut.

Um weitere Informationen zu erhalten, können Sie Leelands Blog Nicht mehr zu finden gültiger Zertifizierungspfad für angeforderte Ziel '

44
Pascal Thivent

Neben der richtigen Antwort von Pascal Thivent können Sie das Zertifikat auch in Firefox (Zertifikat anzeigen -> Details -> Export) oder openssl s_client speichern und in den Trust Store importieren.

Sie sollten dies nur tun, wenn Sie das Zertifikat überprüfen können. Andernfalls wird beim ersten Verbindungsaufbau ein Fehler angezeigt, wenn sich das Zertifikat bei nachfolgenden Verbindungen unerwartet ändert.

Verwenden Sie zum Importieren in einen Trust Store:

keytool -importcert -keystore truststore.jks -file servercert.pem

Standardmäßig sollte der Standard-Truststore lib/security/cacerts sein, und das Kennwort sollte changeit sein. Weitere Informationen finden Sie im JSSE-Referenzhandbuch .

Wenn Sie dieses Zertifikat nicht global zulassen möchten, sondern nur für diese Verbindungen, können Sie ein SSLContext für es erstellen:

TrustManagerFactory tmf = TrustManagerFactory
    .getInstance(TrustManagerFactory.getDefaultAlgorithm());
KeyStore ks = KeyStore.getInstance("JKS");
FileInputStream fis = new FileInputStream("/.../truststore.jks");
ks.load(fis, null);
// or ks.load(fis, "thepassword".toCharArray());
fis.close();

tmf.init(ks);

SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, tmf.getTrustManagers(), null);

Dann müssen Sie es für Apache HTTP Client 3.x einrichten, indem Sie einen der Parameter SecureProtocolSocketFactory implementieren, um diesen SSLContext zu verwenden. (Es gibt Beispiele hier ).

Apache HTTP Client 4.x (abgesehen von der ersten Version) hat direkte Unterstützung für die Weitergabe einer SSLContext.

23
Bruno

Von  http://hc.Apache.org/httpclient-3.x/sslguide.html:

Protocol.registerProtocol("https", 
new Protocol("https", new MySSLSocketFactory(), 443));
HttpClient httpclient = new HttpClient();
GetMethod httpget = new GetMethod("https://www.whatever.com/");
try {
  httpclient.executeMethod(httpget);
      System.out.println(httpget.getStatusLine());
} finally {
      httpget.releaseConnection();
}

Wo das MySSLSocketFactory-Beispiel zu finden ist hier . Es verweist auf eine TrustManager, die Sie ändern können, um alles zu vertrauen (obwohl Sie dies berücksichtigen müssen!)

10
Bozho

Der Apache HttpClient 4.5 Weg:

org.Apache.http.ssl.SSLContextBuilder sslContextBuilder = SSLContextBuilder.create();
sslContextBuilder.loadTrustMaterial(new org.Apache.http.conn.ssl.TrustSelfSignedStrategy());
SSLContext sslContext = sslContextBuilder.build();
org.Apache.http.conn.ssl.SSLConnectionSocketFactory sslSocketFactory =
        new SSLConnectionSocketFactory(sslContext, new org.Apache.http.conn.ssl.DefaultHostnameVerifier());

HttpClientBuilder httpClientBuilder = HttpClients.custom().setSSLSocketFactory(sslSocketFactory);
httpClient = httpClientBuilder.build();

HINWEIS: org.Apache.http.conn.ssl.SSLContextBuilder ist deprecated und org.Apache.http.ssl.SSLContextBuilder ist der neue (Hinweis conn fehlt im Paketnamen des letzteren).

9
Anton Krosnev

Wenn Sie über einen Java Cert Store verfügen (mithilfe der oben erstellten great InstallCert-Klasse), können Sie Java dazu verwenden, diesen zu verwenden, indem Sie beim Start von Java den Parameter "javax.net.ssl.trustStore" übergeben. 

Ex:

Java -Djavax.net.ssl.trustStore=/path/to/jssecacerts MyClassName
4
Brian M. Carr

Für Apache HttpClient 4.5+ und Java8:

SSLContext sslContext = SSLContexts.custom()
        .loadTrustMaterial((chain, authType) -> true).build();

SSLConnectionSocketFactory sslConnectionSocketFactory =
        new SSLConnectionSocketFactory(sslContext, new String[]
        {"SSLv2Hello", "SSLv3", "TLSv1","TLSv1.1", "TLSv1.2" }, null,
        NoopHostnameVerifier.INSTANCE);
CloseableHttpClient client = HttpClients.custom()
        .setSSLSocketFactory(sslConnectionSocketFactory)
        .build();

Wenn Ihr HttpClient jedoch einen ConnectionManager zum Suchen einer Verbindung verwendet, z. so was:

 PoolingHttpClientConnectionManager connectionManager = new 
         PoolingHttpClientConnectionManager();

 CloseableHttpClient client = HttpClients.custom()
            .setConnectionManager(connectionManager)
            .build();

Die HttpClients.custom().setSSLSocketFactory(sslConnectionSocketFactory) hat keine Auswirkung , das Problem ist nicht gelöst.

Der HttpClient verwendet den angegebenen connectionManager zum Suchen einer Verbindung, und der angegebene connectionManager hat unsere angepasste SSLConnectionSocketFactory nicht registriert. Um dieses Problem zu beheben, sollten Sie die angepasste SSLConnectionSocketFactory im connectionManager registrieren. Der korrekte Code sollte so aussehen:

PoolingHttpClientConnectionManager connectionManager = new 
    PoolingHttpClientConnectionManager(RegistryBuilder.
                <ConnectionSocketFactory>create()
      .register("http",PlainConnectionSocketFactory.getSocketFactory())
      .register("https", sslConnectionSocketFactory).build());

CloseableHttpClient client = HttpClients.custom()
            .setConnectionManager(connectionManager)
            .build();
4
EyouGo

Ein weiteres Problem, auf das Sie bei selbst signierten Testzertifikaten stoßen können, ist folgendes:

Java.io.IOException: HTTPS-Hostname falsch: sollte sein ...

Dieser Fehler tritt auf, wenn Sie versuchen, auf eine HTTPS-URL zuzugreifen. Möglicherweise haben Sie das Serverzertifikat bereits im Keystore Ihres JRE installiert. Dieser Fehler bedeutet jedoch, dass der Name des Serverzertifikats nicht mit dem tatsächlichen Domänennamen des Servers übereinstimmt, der in der URL angegeben ist. Dies ist normalerweise der Fall, wenn Sie ein nicht von einer Zertifizierungsstelle ausgestelltes Zertifikat verwenden.

In diesem Beispiel wird veranschaulicht, wie ein HttpsURLConnection-DefaultHostnameVerifier geschrieben wird, der den Zertifikatservernamen ignoriert:

http://www.Java-samples.com/showtutorial.php?tutorialid=211

3
Kiwicmc

Probieren Sie den Code hier aus, um auf einfache Weise Hosts hinzuzufügen, denen Sie zur Laufzeit vertrauen, ohne alle Prüfungen auszulösen: http://code.google.com/p/self-signed-cert-trust-manager/ .

2
Matt Olsen

EasySSLProtocolSocketFactory bereitete mir Probleme, sodass ich meine eigene ProtocolSocketFactory implementieren musste. 

Zuerst müssen Sie es registrieren: 

Protocol.registerProtocol("https", new Protocol("https", new TrustAllSSLSocketFactory(), 443));

HttpClient client = new HttpClient();
...

Dann implementieren Sie ProtocolSocketFactory:

class TrustAllSSLSocketFactory implements ProtocolSocketFactory {

    public static final TrustManager[] TRUST_ALL_CERTS = new TrustManager[]{
        new X509TrustManager() {
            public void checkClientTrusted(final X509Certificate[] certs, final String authType) {

            }

            public void checkServerTrusted(final X509Certificate[] certs, final String authType) {

            }

            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }
        }
    };

    private TrustManager[] getTrustManager() {
        return TRUST_ALL_CERTS;
    }

    public Socket createSocket(final String Host, final int port, final InetAddress clientHost,
                               final int clientPort) throws IOException {
        return getSocketFactory().createSocket(Host, port, clientHost, clientPort);
    }

    @Override
    public Socket createSocket(final String Host, final int port, final InetAddress localAddress,
                               final int localPort, final HttpConnectionParams params) throws IOException {
        return createSocket(Host, port);
    }

    public Socket createSocket(final String Host, final int port) throws IOException {
        return getSocketFactory().createSocket(Host, port);
    }

    private SocketFactory getSocketFactory() throws UnknownHostException {
        TrustManager[] trustAllCerts = getTrustManager();

        try {
            SSLContext context = SSLContext.getInstance("SSL");
            context.init(null, trustAllCerts, new SecureRandom());

            final SSLSocketFactory socketFactory = context.getSocketFactory();
            HttpsURLConnection.setDefaultSSLSocketFactory(socketFactory);
            return socketFactory;
        } catch (NoSuchAlgorithmException | KeyManagementException exception) {
            throw new UnknownHostException(exception.getMessage());
        }
    }
}

Hinweis: Dies gilt für HttpClient 3.1 und Java 8

1
Daniel Treiber

befolgen Sie die Anweisungen für Java 1.7, um ein SSL-Zertifikat mit der Programmdatei InstallCert.Java zu erstellen.

https://github.com/escline/InstallCert

sie müssen den Tomcat neu starten

0
Allahbakash.G

Ich benutze httpclient 3.1.X und das funktioniert für mich 

        try {
        SSLContext sslContext = SSLContext.getInstance("TLS");
        TrustManager trustManager = new X509TrustManager() {
            @Override
            public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
            }

            @Override
            public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {

            }

            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }
        };
        sslContext.init(null, new TrustManager[]{trustManager}, null);
        SslContextSecureProtocolSocketFactory socketFactory = new SslContextSecureProtocolSocketFactory(sslContext,false);
        Protocol.registerProtocol("https", new Protocol("https", (ProtocolSocketFactory) socketFactory, 443));//同样会影响到HttpUtils
    } catch (Throwable e) {
        e.printStackTrace();

}

public class SslContextSecureProtocolSocketFactory implements      SecureProtocolSocketFactory {

private SSLContext sslContext;
private boolean verifyHostname;

public SslContextSecureProtocolSocketFactory(SSLContext sslContext, boolean verifyHostname) {
    this.verifyHostname = true;
    this.sslContext = sslContext;
    this.verifyHostname = verifyHostname;
}

public SslContextSecureProtocolSocketFactory(SSLContext sslContext) {
    this(sslContext, true);
}

public SslContextSecureProtocolSocketFactory(boolean verifyHostname) {
    this((SSLContext)null, verifyHostname);
}

public SslContextSecureProtocolSocketFactory() {
    this((SSLContext)null, true);
}

public synchronized void setHostnameVerification(boolean verifyHostname) {
    this.verifyHostname = verifyHostname;
}

public synchronized boolean getHostnameVerification() {
    return this.verifyHostname;
}

public Socket createSocket(String Host, int port, InetAddress clientHost, int clientPort) throws IOException, UnknownHostException {
    SSLSocketFactory sf = this.getSslSocketFactory();
    SSLSocket sslSocket = (SSLSocket)sf.createSocket(Host, port, clientHost, clientPort);
    this.verifyHostname(sslSocket);
    return sslSocket;
}

public Socket createSocket(String Host, int port, InetAddress localAddress, int localPort, HttpConnectionParams params) throws IOException, UnknownHostException, ConnectTimeoutException {
    if(params == null) {
        throw new IllegalArgumentException("Parameters may not be null");
    } else {
        int timeout = params.getConnectionTimeout();
        Socket socket = null;
        SSLSocketFactory socketfactory = this.getSslSocketFactory();
        if(timeout == 0) {
            socket = socketfactory.createSocket(Host, port, localAddress, localPort);
        } else {
            socket = socketfactory.createSocket();
            InetSocketAddress localaddr = new InetSocketAddress(localAddress, localPort);
            InetSocketAddress remoteaddr = new InetSocketAddress(Host, port);
            socket.bind(localaddr);
            socket.connect(remoteaddr, timeout);
        }

        this.verifyHostname((SSLSocket)socket);
        return socket;
    }
}

public Socket createSocket(String Host, int port) throws IOException, UnknownHostException {
    SSLSocketFactory sf = this.getSslSocketFactory();
    SSLSocket sslSocket = (SSLSocket)sf.createSocket(Host, port);
    this.verifyHostname(sslSocket);
    return sslSocket;
}

public Socket createSocket(Socket socket, String Host, int port, boolean autoClose) throws IOException, UnknownHostException {
    SSLSocketFactory sf = this.getSslSocketFactory();
    SSLSocket sslSocket = (SSLSocket)sf.createSocket(socket, Host, port, autoClose);
    this.verifyHostname(sslSocket);
    return sslSocket;
}

private void verifyHostname(SSLSocket socket) throws SSLPeerUnverifiedException, UnknownHostException {
    synchronized(this) {
        if(!this.verifyHostname) {
            return;
        }
    }

    SSLSession session = socket.getSession();
    String hostname = session.getPeerHost();

    try {
        InetAddress.getByName(hostname);
    } catch (UnknownHostException var10) {
        throw new UnknownHostException("Could not resolve SSL sessions server hostname: " + hostname);
    }

    X509Certificate[] certs = (X509Certificate[])((X509Certificate[])session.getPeerCertificates());
    if(certs != null && certs.length != 0) {
        X500Principal subjectDN = certs[0].getSubjectX500Principal();
        List cns = this.getCNs(subjectDN);
        boolean foundHostName = false;
        Iterator i$ = cns.iterator();
        AntPathMatcher matcher  = new AntPathMatcher();
        while(i$.hasNext()) {
            String cn = (String)i$.next();
            if(matcher.match(cn.toLowerCase(),hostname.toLowerCase())) {
                foundHostName = true;
                break;
            }
        }

        if(!foundHostName) {
            throw new SSLPeerUnverifiedException("HTTPS hostname invalid: expected \'" + hostname + "\', received \'" + cns + "\'");
        }
    } else {
        throw new SSLPeerUnverifiedException("No server certificates found!");
    }
}

private List<String> getCNs(X500Principal subjectDN) {
    ArrayList cns = new ArrayList();
    StringTokenizer st = new StringTokenizer(subjectDN.getName(), ",");

    while(st.hasMoreTokens()) {
        String cnField = st.nextToken();
        if(cnField.startsWith("CN=")) {
            cns.add(cnField.substring(3));
        }
    }

    return cns;
}

protected SSLSocketFactory getSslSocketFactory() {
    SSLSocketFactory sslSocketFactory = null;
    synchronized(this) {
        if(this.sslContext != null) {
            sslSocketFactory = this.sslContext.getSocketFactory();
        }
    }

    if(sslSocketFactory == null) {
        sslSocketFactory = (SSLSocketFactory)SSLSocketFactory.getDefault();
    }

    return sslSocketFactory;
}

public synchronized void setSSLContext(SSLContext sslContext) {
    this.sslContext = sslContext;
}

}

0
acoder2013

möchte die Antwort hier einfügen:

in Apache HttpClient 4.5.5

Wie gehe ich mit einem ungültigen SSL-Zertifikat mit Apache-Client 4.5.5 um?

HttpClient httpClient = HttpClients
            .custom()
            .setSSLContext(new SSLContextBuilder().loadTrustMaterial(null, TrustAllStrategy.INSTANCE).build())
            .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
            .build();
0
aaron

Die InstallCert-Methode zum Generieren der jssecacerts-Datei zu verwenden und -Djavax.net.ssl.trustStore=/path/to/jssecacerts zu erstellen, hat großartig funktioniert.

0
Dexin Wang

Für HttpClient können wir Folgendes tun:

SSLContext ctx = SSLContext.getInstance("TLS");
        ctx.init(new KeyManager[0], new TrustManager[] {new DefaultTrustManager()}, new SecureRandom());
        SSLContext.setDefault(ctx);

        String uri = new StringBuilder("url").toString();

        HostnameVerifier hostnameVerifier = new HostnameVerifier() {
            @Override
            public boolean verify(String arg0, SSLSession arg1) {
                return true;
            }
        };

        HttpClient client = HttpClientBuilder.create().setSSLContext(ctx)
                .setSSLHostnameVerifier(hostnameVerifier).build()
0
sorabh solanki

Ich hatte zufällig das gleiche Problem, plötzlich fehlten alle meine Importe. Ich habe versucht, alle Inhalte in meinem .m2-Ordner zu löschen. Und der Versuch, alles erneut zu importieren, funktionierte aber immer noch nicht. Schließlich habe ich die Website geöffnet, für die sich die IDE beschwert hat, dass sie in meinem Browser nicht heruntergeladen werden konnte. Und sah das Zertifikat, das es verwendete, und sah in meinem

$ keytool -v -list  PATH_TO_Java_KEYSTORE

Der Pfad zu meinem Keystore war /Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home/jre/lib/security/cacerts

dieses spezielle Zertifikat war nicht da.

Alles, was Sie tun müssen, ist, das Zertifikat erneut in den Java JVM-Keystore zu stellen. Dies kann mit dem folgenden Befehl erfolgen.

$ keytool -import -alias ANY_NAME_YOU_WANT_TO_GIVE -file PATH_TO_YOUR_CERTIFICATE -keystore PATH_OF_Java_KEYSTORE

Wenn Sie nach einem Kennwort gefragt werden, versuchen Sie es mit dem Standardkennwort "changeit". Wenn beim Ausführen des obigen Befehls ein Berechtigungsfehler auftritt. In Windows öffnen Sie es im Administrationsmodus. Verwenden Sie unter Mac und Unix Sudo.

Nachdem Sie den Schlüssel erfolgreich hinzugefügt haben, können Sie ihn folgendermaßen anzeigen:

$ keytool -v -list  /Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home/jre/lib/security/cacerts 

Sie können nur den SHA-1 mit dem Befehl anzeigen

$ keytool -list  /Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home/jre/lib/security/cacerts 
0
Adarsh S N

Dieser Link erklärt Ihnen Schritt für Schritt, welche Anforderungen Sie haben. Wenn Sie nicht wirklich wissen, um welches Zertifikat es sich handelt, können Sie den unten stehenden Link ausführen. 

Hinweis Möglicherweise möchten Sie noch einmal überprüfen, was Sie tun, da dies eine unsichere Operation ist.

0
Raghu Kiran

Verwendete das folgende zusammen mit DefaultTrustManager und es funktionierte in httpclient wie Charme. Danke vielmals!! @ Kevin und alle anderen Mitwirkenden

    SSLContext ctx = null;
    SSLConnectionSocketFactory sslsf = null;
    try {

        ctx = SSLContext.getInstance("TLS");
        ctx.init(new KeyManager[0], new TrustManager[] {new DefaultTrustManager()}, new SecureRandom());
        SSLContext.setDefault(ctx);

        sslsf = new SSLConnectionSocketFactory(
                ctx,
                new String[] { "TLSv1" },
                null,
                SSLConnectionSocketFactory.getDefaultHostnameVerifier());

    } catch (Exception e) {
        e.printStackTrace();
    }

     CloseableHttpClient client = HttpClients.custom()
            .setSSLSocketFactory(sslsf)
            .build();