Как обрабатывать недействительные SSL-сертификаты с помощью Apache HttpClient?

Я знаю, есть много разных вопросов и столько ответов по этой проблеме ... Но я не могу понять ...

У меня: ubuntu-9.10-desktop-amd64 + NetBeans6.7.1 установлен "как есть" с офф. респ. Мне нужно подключиться к какому-либо сайту через HTTPS. Для этого я использую HttpClient от Apache.

Из учебника я прочитал:

«После того, как вы правильно установили JSSE, безопасная связь HTTP через SSL должна быть такой же
простой, как обычная связь HTTP». И пример:

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

К настоящему времени я пишу это:

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

В результате у меня есть набор ошибок:

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

Что мне нужно сделать, чтобы создать простейшее SSL-соединение? (Вероятно, без KeyManager, Trust manager и т. Д. Пока.)


person rauch    schedule 01.12.2009    source источник
comment
Сертификат SSL этого конкретного сайта настроен неправильно. Когда я захожу на mms.nw.ru, в Chrome появляется экран с ошибкой.   -  person Trevor Harrison    schedule 01.12.2009
comment
Прежде всего, импортируйте свой crt файл в {JAVA_HOME} / jre / security / cacerts, если вы все еще сталкиваетесь с этим исключением, измените свою версию jdk. Например с jdk1.8.0_17 на jdk1.8.0_231   -  person Tohid Makari    schedule 02.02.2021


Ответы (18)


https://mms.nw.ru использует самозаверяющий сертификат, которого нет в наборе диспетчера доверия по умолчанию. Чтобы решить эту проблему, выполните одно из следующих действий:

  • Настройте SSLContext с TrustManager, который принимает любой сертификат (см. Ниже).
  • Настройте SSLContext с соответствующим хранилищем доверенных сертификатов, которое включает ваш сертификат.
  • Добавьте сертификат для этого сайта в хранилище доверенных сертификатов Java по умолчанию.

Вот программа, которая создает (в основном бесполезный) контекст SSL, который принимает любой сертификат:

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;
        }
    }
}
person Kevin    schedule 01.12.2009
comment
Можно ли интегрировать этот подход с HttpClient вместо URLConnection? - person stormin986; 30.04.2010
comment
Да, документы HttpClient должны рассказать вам, как подключить собственный SSLContext - person Kevin; 30.04.2010
comment
Вы можете подключить SSLContext с HTTP-клиентом Apache 3.x, используя это: code.google. com / p / jsslutils / wiki / ApacheHttpClientUsage Теперь есть встроенная поддержка использования SSLContext в HTTP-клиенте Apache 4.x. - person Bruno; 14.09.2010
comment
Конечно, следует отметить, что этот подход (SSL-контекст, который принимает любой сертификат) делает соединение уязвимым для активных атак MITM. - person Bruno; 02.05.2012
comment
FYI SSLContext.setDefault () - это метод Java 1.7+. - person Chris; 14.06.2012
comment
эта запись диспетчера доверия разрешила мое исключение javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: якорь доверия для пути сертификации не найден. - person Shailendra Singh Rajawat; 14.05.2013
comment
Обновление для версии 4.3: SSLContext sslContext = SSLContexts.custom (). LoadTrustMaterial (null, new TrustSelfSignedStrategy ()). UseTLS (). Build (); SSLConnectionSocketFactory connectionFactory = новый SSLConnectionSocketFactory (sslContext, новый AllowAllHostnameVerifier ()); - person Jay; 17.12.2013
comment
Вместо того, чтобы устанавливать по умолчанию, вы можете установить его только для этого соединения. conn.setSSLSocketFactory(ctx.getSocketFactory()) - person jiggy; 30.04.2014
comment
Спасибо, это также решило проблему, которая у нас была с соединением RMI (через SSL) - person demaniak; 27.05.2015
comment
К вашему сведению, я пытаюсь сгруппировать эти советы в один помощник: UnsafeSSLHelper. Вы можете попробовать это с помощью Apache HttpClient 4.3.6. UnsafeSSLHelper unsafeSSLHelper = new UnsafeSSLHelper(); CloseableHttpClient client = HttpClientBuilder.create().setSslcontext(unsafeSSLHelper.createUnsecureSSLContext()).setHostnameVerifier(unsafeSSLHelper.getPassiveX509HostnameVerifier()).build(); - person boly38; 10.06.2015
comment
Как мы можем реализовать один и тот же код в HttpClient API и в RestTemplates? Пожалуйста, помогите ... С уважением, Неха - person ; 07.01.2016
comment
Мне было интересно .. Почему так много разработчиков настаивают на таком подходе к принятию всех сертификатов SSL? ИМХО, это полностью противоречит цели решения (шифрование HTTP-трафика). - person ivanleoncz; 18.09.2016
comment
Убедитесь, что у вас правильный контекст SSL, например. : SSLContext ctx = SSLContext.getInstance (TLSv1.2); - person Imran; 22.12.2016
comment
Привет, вы можете помочь мне решить эту проблему? stackoverflow.com/questions/57224929/ Это очень похоже. Я хочу попытаться исправить это с помощью conda, если это возможно, чтобы я мог экспортировать среду, которая работает. - person O.rka; 26.07.2019
comment
Следует отметить, и вы должны были сами заметить, что диспетчер доверия, указанный в этом ответе, радикально небезопасен. Вы не должны использовать этот код. - person user207421; 23.08.2019

https://mms.nw.ru, вероятно, использует сертификат, выданный не центром сертификации. Следовательно, вам необходимо добавить сертификат в надежное хранилище ключей Java, как описано в невозможно найти действительный путь сертификации. к запрошенной цели:

При работе с клиентом, который работает с сервером с поддержкой SSL, работающим по протоколу https, вы можете получить ошибку «не удается найти действительный путь сертификации для запрошенной цели», если сертификат сервера не выпущен центром сертификации, а самоподписан или выпущен частная CMS.

Не паникуйте. Все, что вам нужно сделать, это добавить сертификат сервера в надежное хранилище ключей Java, если ваш клиент написан на Java. Вам может быть интересно, как будто вы не можете получить доступ к машине, на которой установлен сервер. Есть простая программа, которая может вам помочь. Загрузите Java-программа и запустите

% java InstallCert _web_site_hostname_

Эта программа открыла соединение с указанным хостом и начала квитирование SSL. Он распечатал трассировку стека исключений возникшей ошибки и показывает сертификаты, используемые сервером. Теперь он предлагает вам добавить сертификат в надежное хранилище ключей.

Если вы передумали, введите «q». Если вы действительно хотите добавить сертификат, введите «1» или другие числа, чтобы добавить другие сертификаты, даже сертификат CA, но обычно вы не хотите этого делать. После того, как вы сделаете свой выбор, программа отобразит полный сертификат и затем добавит его в хранилище ключей Java с именем jssecacerts в текущем каталоге.

Чтобы использовать его в своей программе, либо настройте JSSE для использования его в качестве хранилища доверенных сертификатов, либо скопируйте его в свой каталог $ JAVA_HOME / jre / lib / security. Если вы хотите, чтобы все приложения Java распознавали сертификат как доверенный, а не только JSSE, вы также можете перезаписать файл cacerts в этом каталоге.

После всего этого JSSE сможет выполнить рукопожатие с хостом, что вы можете проверить, снова запустив программу.

Чтобы получить более подробную информацию, вы можете посетить блог Лиланда Больше нет" невозможно найти действительный путь сертификации к запрошенной цели "

person Pascal Thivent    schedule 01.12.2009
comment
Вы не можете добавить сертификат SSL для каждого веб-сайта в мире с недействительным сертификатом ssl. - person Jay; 04.05.2011
comment
@Jacob, Паскаль прав, вам следует проверить сертификат сайта, к которому вы подключаетесь. Аутентификация сервера - важная часть защиты SSL-соединения. - person Bruno; 02.05.2012
comment
Слегка измененная версия этой программы доступна по адресу infposs.blogspot. it / 2013/06 / installcert-and-java-7.html Решает проблему с Java 7 (исключение UnsupportedOperationExcetpion при запуске InstallCert во второй раз для проверки правильности установки сертификата). - person Pino; 12.02.2014
comment
К сожалению, он не поддерживает прокси. - person Cheruvim; 14.01.2015
comment
Спасибо за это решение, у меня это сработало - person Vipul Jain; 26.12.2016
comment
Ссылка на программу Java в ответе ведет к ужасной странице практически мертвого (не зря!) Кода Google, заполненной десятками файлов, с указанием no, что вам действительно нужен только single .java file ... или с чего начать. Ссылка, опубликованная @Pino, позволяет легко увидеть ... насколько это на самом деле просто. Grazie Pino! - person Lambart; 06.07.2017

В дополнение к правильному ответу Паскаля Тивента есть еще один способ - сохранить сертификат из Firefox (Просмотр сертификата -> Детали -> экспорт) или openssl s_client и импортировать его в хранилище доверенных сертификатов.

Вы должны делать это только в том случае, если у вас есть способ проверить этот сертификат. В противном случае сделайте это при первом подключении, это, по крайней мере, выдаст вам ошибку, если сертификат неожиданно изменится при последующих подключениях.

Чтобы импортировать его в хранилище доверенных сертификатов, используйте:

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

По умолчанию хранилище доверенных сертификатов по умолчанию должно быть $JAVA_HOME/jre/lib/security/cacerts, а его пароль - changeit, см. Справочном руководстве по JSSE.

Если вы не хотите разрешать этот сертификат глобально, а только для этих подключений, можно создать для него SSLContext:

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

Затем вам необходимо настроить его для Apache HTTP Client 3.x, реализовав его, если его _ 7_, чтобы использовать это SSLContext. (Примеры приведены здесь).

HTTP-клиент Apache 4.x (кроме самой ранней версии) имеет прямую поддержку передачи SSLContext.

person Bruno    schedule 02.05.2012

Способ Apache HttpClient 4.5:

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

ПРИМЕЧАНИЕ. org.apache.http.conn.ssl.SSLContextBuilder не рекомендуется, а org.apache.http.ssl.SSLContextBuilder - новый (примечание conn отсутствует в названии последнего пакета).

person Anton Krosnev    schedule 07.08.2015
comment
Проверка кода 4.5: SSLContextBuilder начиная с 4.4 - НЕ лишена. TrustSelfSignedStrategy начиная с версии 4.1 - НЕ устарел. SSLConnectionSocketFactory некоторые конструкторы устарели, а тот, что в примере, НЕ. DefaultHostnameVerifier начиная с 4.4 - НЕ устарело. - person Anton Krosnev; 14.08.2015
comment
Устарело и перемещено на org.apache.http.conn.ssl - person chrislhardin; 14.08.2015
comment
При этом у меня возникает странный эффект: при запуске с консоли он работает (игнорируя хост и действительность сертификата). Если я запускаю его из eclipse, он терпит неудачу с sun.security.validator.ValidatorException: Ошибка построения пути PKIX: sun.security.provider .certpath.SunCertPathBuilderException: невозможно найти действительный путь сертификации для запрошенной цели - person cljk; 19.07.2017

Для Apache HttpClient 4.5+ и 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();

Но если ваш HttpClient использует ConnectionManager для поиска соединения, например вот так:

 PoolingHttpClientConnectionManager connectionManager = new 
         PoolingHttpClientConnectionManager();

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

HttpClients.custom().setSSLSocketFactory(sslConnectionSocketFactory) не действует, проблема не решена.

Потому что HttpClient использует указанный ConnectionManager для поиска соединения, а указанный connectionManager не зарегистрировал наш настроенный SSLConnectionSocketFactory. Чтобы решить эту проблему, необходимо зарегистрировать настроенный SSLConnectionSocketFactory в connectionManager. Правильный код должен выглядеть так:

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

CloseableHttpClient client = HttpClients.custom()
            .setConnectionManager(connectionManager)
            .build();
person EyouGo    schedule 17.08.2017
comment
Ты спас мне день! Я все время задавался вопросом, почему setSSLSocketFactory вообще не действует. Я не понимал, что вместо этого мне нужно зарегистрировать свою фабрику в диспетчере соединений. Спасибо! - person Andrew; 01.06.2018

Из 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();
}

Где можно найти пример MySSLSocketFactory здесь. Он ссылается на TrustManager, который вы можете изменить, чтобы доверять всему (хотя вы должны это учитывать!)

person Bozho    schedule 01.12.2009

Если у вас есть Java Cert Store (используя созданный выше отличный класс InstallCert), вы можете заставить Java использовать его, передав параметр javax.net.ssl.trustStore при запуске java.

Ex:

java -Djavax.net.ssl.trustStore=/path/to/jssecacerts MyClassName
person Brian M. Carr    schedule 01.12.2009
comment
Спасибо! Ты спас мне день! Я думал, что когда вы использовали / jre для JAVA_HOME, файл /jre/lib/security/cacerts будет использоваться, но ... очевидно, что это не тот случай, и ваши настройки просто волшебным образом заставили все работать .. :-) - person Christophe Muller; 15.12.2020

хочу вставить ответ сюда:

в Apache HttpClient 4.5.5

Как обрабатывать недействительный сертификат SSL с помощью Apache клиент 4.5.5?

HttpClient httpClient = HttpClients
            .custom()
            .setSSLContext(new SSLContextBuilder().loadTrustMaterial(null, TrustAllStrategy.INSTANCE).build())
            .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
            .build();
person aaron    schedule 15.02.2019
comment
из какого пакета SSLContextBuilder? - person zygimantus; 04.11.2020

Другая проблема, с которой вы можете столкнуться с самоподписанными тестовыми сертификатами, заключается в следующем:

java.io.IOException: неправильное имя хоста HTTPS: должно быть ...

Эта ошибка возникает, когда вы пытаетесь получить доступ к URL-адресу HTTPS. Возможно, вы уже установили сертификат сервера в хранилище ключей JRE. Но эта ошибка означает, что имя сертификата сервера не совпадает с фактическим доменным именем сервера, указанным в URL-адресе. Обычно это происходит, когда вы используете сертификат, выданный не CA.

В этом примере показано, как написать HttpsURLConnection DefaultHostnameVerifier, который игнорирует имя сервера сертификатов:

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

person Kiwicmc    schedule 25.08.2011
comment
Ссылка не работает :( - person Jan Petzold; 16.02.2017

EasySSLProtocolSocketFactory вызывал у меня проблемы, поэтому в итоге я реализовал свой собственный ProtocolSocketFactory.

Для начала нужно его зарегистрировать:

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

HttpClient client = new HttpClient();
...

Затем реализуйте 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());
        }
    }
}

Примечание: это с HttpClient 3.1 и Java 8

person Daniel Treiber    schedule 08.05.2017
comment
все еще происходит исключение! - person riya ahuja; 24.09.2017

Чтобы легко добавить узлы, которым вы доверяете, во время выполнения, не отбрасывая всех проверок, попробуйте следующий код: http://code.google.com/p/self-signed-cert-trust-manager/.

person Matt Olsen    schedule 30.01.2012

Я столкнулся с той же проблемой, внезапно весь мой импорт пропал. Я попытался удалить все содержимое моей папки .m2. И пытался повторно импортировать все, но все равно ничего не работало. Наконец, я открыл веб-сайт, на который среда IDE жаловалась на невозможность загрузки в моем браузере. И увидел сертификат, который он использовал, и увидел в моем

$ keytool -v -list  PATH_TO_JAVA_KEYSTORE

Путь к моему хранилищу ключей был /Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home/jre/lib/security/cacerts

этого конкретного сертификата там не было.

Итак, все, что вам нужно сделать, это снова поместить сертификат в хранилище ключей JAVA JVM. Это можно сделать с помощью следующей команды.

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

Если он запрашивает пароль, попробуйте пароль по умолчанию «changeit». Если при выполнении указанной выше команды вы получаете ошибку разрешения. В windows откройте его в режиме администрирования. В mac и unix используйте sudo.

После того, как вы успешно добавили ключ, вы можете просмотреть его, используя:

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

Вы можете просмотреть только SHA-1, используя команду teh

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

Эта ссылку шаг за шагом объясняет ваше требование. Если вас действительно не интересует, какой сертификат, вы можете продолжить процесс по ссылке ниже.

Примечание. Возможно, вы захотите дважды проверить, что вы делаете, поскольку это небезопасная операция.

person Raghu Kiran    schedule 05.03.2012
comment
вам действительно стоит привести некоторые из ваших собственных объяснений или примеров, ответ, который просто указывает на ссылку, будет бесполезен, если эта ссылка когда-либо сломается. - person svarog; 22.06.2016

Использование InstallCert для создания jssecacerts файла и -Djavax.net.ssl.trustStore=/path/to/jssecacerts отлично сработало.

person Dexin Wang    schedule 28.01.2012

Я использую httpclient 3.1.X, и у меня это работает

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

}

person acoder2013    schedule 14.10.2016

Для HttpClient мы можем сделать это:

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()
person sorabh solanki    schedule 23.05.2018

следуйте инструкциям, приведенным ниже для Java 1.7, чтобы создать сертификат SSL с помощью программного файла InstallCert.java.

https://github.com/escline/InstallCert

вы должны перезапустить кота

person Allahbakash.G    schedule 18.12.2018

Использовал следующее вместе с DefaultTrustManager, и он работал в httpclient как charm. Благодаря тонну!! @Kevin и все остальные участники

    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();
person Mohankumar Loganathan    schedule 19.01.2019