// Create a trust manager that does not validate certificate chains TrustManager[] trustAllCerts = newTrustManager[] { newX509TrustManager() { public java.security.cert.X509Certificate[] getAcceptedIssuers() { returnnewX509Certificate[0]; } publicvoidcheckClientTrusted( java.security.cert.X509Certificate[] certs, String authType) { } publicvoidcheckServerTrusted( java.security.cert.X509Certificate[] certs, String authType) { } } };
// Install the all-trusting trust manager try { SSLContextsc= SSLContext.getInstance("SSL"); sc.init(null, trustAllCerts, newjava.security.SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); } catch (GeneralSecurityException e) { } // Now you can access an https URL without having the certificate in the truststore try { URLurl=newURL("https://hostname/index.html"); } catch (MalformedURLException e) { }
Обратите внимание, что я вообще не рекомендую вариант № 2. Отключение менеджера доверия приводит к повреждению некоторых частей SSL и делает вас уязвимыми для атак "человек посередине". Предпочтите вариант № 1 или, что еще лучше, попросите сервер использовать "настоящий" сертификат, подписанный хорошо известным центром сертификации.
Ответ 2
Есть лучшая альтернатива доверять всем сертификатам: создайте TrustStore который конкретно доверяет данному сертификату и используйте это для создания SSLContext из которого можно получить SSLSocketFactory для установки на HttpsURLConnection. Вот полный код:
FilecrtFile=newFile("server.crt"); Certificatecertificate= CertificateFactory.getInstance("X.509").generateCertificate(newFileInputStream(crtFile)); // Or if the crt-file is packaged into a jar file: // CertificateFactory.getInstance("X.509").generateCertificate(this.class.getClassLoader().getResourceAsStream("server.crt"));
В качестве альтернативы вы можете загрузить KeyStore непосредственно из файла или получить сертификат X.509 из любого надежного источника.
Обратите внимание, что с этим кодом сертификаты из cacerts использоваться не будут. Этот конкретный HttpsURLConnection будет доверять только этому конкретному сертификату.
Ответ 3
Apache HttpClient 4.5 поддерживает прием самозаверяющих сертификатов:
Это создает фабрику SSL-сокетов, которая будет использовать TrustSelfSignedStrategy, регистрирует ее в пользовательском диспетчере подключений, а затем выполняет HTTP GET с использованием этого менеджера подключений.
Я согласен с теми, кто скандирует "не делайте этого в production", однако существуют варианты использования для принятия самозаверяющих сертификатов вне production; мы используем их в автоматизированных интеграционных тестах, так что мы используем SSL (как в production), даже когда не работаем на производственном оборудовании.
Итак, чтобы подключиться к интересующему меня домену, от которого был выдан сертификат, identrust.com я выполнил следующие шаги. По сути, мне нужно было получить сертификат identrust.com (DST Root CA X3), которому JVM будет доверять. Я смог сделать это с помощью Apache HttpComponents 4.5 примерно так:
2: Сохраните строку в файл с именем "DST Root CA X3.pem". Обязательно добавьте строки "-----BEGIN CERTIFICATE-----" и "-----END CERTIFICATE----" в файл в начале и конце.
3. Создайте файл хранилища ключей java, cacerts.jks, с помощью следующей команды:
4. Скопируйте результирующее хранилище ключей cacerts.jks в каталог ресурсов вашего java / (maven) приложения.
5. Используйте следующий код, чтобы загрузить этот файл и прикрепить его к Apache 4.5 HttpClient. Это решит проблему для всех доменов, у которых есть сертификаты, выданные от indetrust.com util oracle включает сертификат в хранилище ключей JRE по умолчанию.
Когда проект будет собран, cacerts.jks будет скопирован в classpath и загружен оттуда. На данный момент я не тестировал другие ssl-сайты, но если приведенный выше код "соединится" в этом сертификате, то они тоже будут работать, но опять же, я не знаю.