Сертификаты Java и SSL
Я пытаюсь установить соединение с моим PHP-скриптом на Java с использованием уровня защищенных сокетов (HTTPS), но я обнаружил, что для обеспечения максимальной безопасности/достоверности я должен импортировать сертификат SSL, который мой веб-сайт использует в моем приложении... Что-то, что я не знаю, как сделать.
Если это помогает, мой SSL-сертификат не является самоподписанным, а предоставляется StartSSL, и я использую Eclipse IDE.
Кто-нибудь может указать мне правильное направление? Т.е. какие файлы мне нужны, куда я должен их импортировать и какой код мне нужен в Java и т.д.?
Ответы
Ответ 1
Я выяснил, что для обеспечения максимальной безопасности/действительности я должен импортировать сертификат SSL, который использует мой веб-сайт в мое приложение
Вы частично правы, когда делаете это выражение. Вам не нужно импортировать сертификат SSL. Достаточно импортировать сертификат CA StartSSL.
Кроме того, не существует такой вещи, как импорт сертификата в приложение Java. Поддержка SSL в Java основана на концепции хранилищ ключей и доверительных сетей, а не на каком-либо сертификате, упакованном в вашем приложении. Если вы публикуете приложение для загрузки и запуска конечных пользователей, вам не нужно публиковать ваш сертификат или, если на то пошло, ваш секретный ключ в вашем приложении. Закрытый ключ и связанный с ним сертификат будут храниться в хранилище ключей, к которому вы можете получить доступ.
Конечные пользователи вашего приложения будут полагаться на поддержку SSL в среде выполнения Java, что позволит приложению устанавливать SSL-соединения с сайтами после проверки сертификата сервера. Время выполнения Java поставляется с набором сертификатов CA по умолчанию в доверенном хранилище, и единственным предварительным условием для успешного подключения SSL является то, что сертификат SSL сервера выдается одним из центров сертификации в доверенном магазине. Сертификаты StartSSL не присутствуют в доверенности среды выполнения Java, по крайней мере, начиная с версии 6, и поэтому:
- Вы можете поручить конечным пользователям выполнить операцию импорта сертификата CA StartSSL в доверенное хранилище Java. Ссылки, которые могут помочь включить этот поток форума StartSSL (для импорта сертификатов CA в доверительный магазин требуется только первые 4 шага), проект GitHub, и это сообщение в блоге; отказ от ответственности - я не пытался использовать ни один из них, и вы должны использовать его на свой страх и риск.
-
Или вы можете инициализировать свое приложение в своем собственном магазине доверия с помощью флагов запуска -Djavax.net.ssl.trustStore=<path_to_truststore> -Djavax.net.ssl.trustStorePassword=<truststore_password>
JVM или выполнить следующий код перед инициализацией соединений SSL:
System.setProperty("javax.net.ssl.trustStore","<path_to_truststore>");
System.setProperty("javax.net.ssl.trustStorePassword","<truststore_password>");
Это жизнеспособный подход, только если ваше приложение является Java SE-приложением, которое не является апплетом (или приложением с аналогичными ограничениями в отношении того, как указан доверенный магазин).
Это также поможет прочитать документацию Java keytool.
Ответ 2
Следующий метод загружает хранилище ключей по умолчанию (cacerts), проверяет, установлен ли сертификат, и устанавливает его, если нет. Это устраняет необходимость вручную запускать команду keystore
на любых серверах.
Предполагается, что пароль хранилища ключей (changeit) по умолчанию не изменяется, обновите CACERTS_PASSWORD
, если нет. Обратите внимание, что метод сохраняет хранилище ключей после добавления сертификата, поэтому после запуска после того, как сертификат будет постоянно находиться в хранилище.
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
/**
* Add a certificate to the cacerts keystore if it not already included
*/
public class SslUtil {
private static final String CACERTS_PATH = "/lib/security/cacerts";
// NOTE: DO NOT STORE PASSWORDS IN PLAIN TEXT CODE, LOAD AT RUNTIME FROM A SECURE CONFIG
// DEFAULT CACERTS PASSWORD IS PROVIDED HERE AS A QUICK, NOT-FOR-PRODUCTION WORKING EXAMPLE
// ALSO, CHANGE THE DEFAULT CACERTS PASSWORD, AS IT IMPLORES YOU TO!
private static final String CACERTS_PASSWORD = "changeit";
/**
* Add a certificate to the cacerts keystore if it not already included
*
* @param alias The alias for the certificate, if added
* @param certInputStream The certificate input stream
* @throws KeyStoreException
* @throws NoSuchAlgorithmException
* @throws CertificateException
* @throws IOException
*/
public static void ensureSslCertIsInKeystore(String alias, InputStream certInputStream)
throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException{
//get default cacerts file
final File cacertsFile = new File(System.getProperty("java.home") + CACERTS_PATH);
if (!cacertsFile.exists()) {
throw new FileNotFoundException(cacertsFile.getAbsolutePath());
}
//load cacerts keystore
FileInputStream cacertsIs = new FileInputStream(cacertsFile);
final KeyStore cacerts = KeyStore.getInstance(KeyStore.getDefaultType());
cacerts.load(cacertsIs, CACERTS_PASSWORD.toCharArray());
cacertsIs.close();
//load certificate from input stream
final CertificateFactory cf = CertificateFactory.getInstance("X.509");
final Certificate cert = cf.generateCertificate(certInputStream);
certInputStream.close();
//check if cacerts contains the certificate
if (cacerts.getCertificateAlias(cert) == null) {
//cacerts doesn't contain the certificate, add it
cacerts.setCertificateEntry(alias, cert);
//write the updated cacerts keystore
FileOutputStream cacertsOs = new FileOutputStream(cacertsFile);
cacerts.store(cacertsOs, CACERTS_PASSWORD.toCharArray());
cacertsOs.close();
}
}
}
Используйте его так:
SslUtil.ensureSslCertIsInKeystore("startssl", new FileInputStream("/path/to/cert.crt"));
Ответ 3
По-видимому, инженеры mailgun почему-то не хотят давать нам четкие инструкции о том, как это решить. Это то, что я сделал
Мы запускаем tomcat8 и подключаемся через веб-службы jersey к API-интерфейсу mailgun. Я следовал этим инструкциям для пользователей и работал нормально. Надеюсь, это поможет кому-то.
На 1/22 мы обновили наши SSL-сертификаты из-за того, что инфраструктура Symantec PKI стала ненадежной. В некоторых более старых версиях Java нет CA DigiCert Global Root G2.
Существует несколько вариантов:
Импортируйте CA "DigiCert Global Root G2" в ваш файл "cacerts".
Обновите JRE до 8u91 (или выше), который включает этот корень.
Чтобы импортировать "DigiCert Global Root G2", вы можете загрузить корень из https://www.digicert.com/digicert-root-certificates.htm. Убедитесь, что вы загружаете правильный корневой сертификат.
Как только сертификат будет загружен, вам нужно будет импортировать его с помощью следующей команды:
keytool -import -trustcacerts -keystore/path/to/cacerts -storepass changeit -noprompt -alias digicert-global-root-g2 -file/path/to/digicert.crt
Вам нужно будет установить путь к вашему Java Keystore и местоположению загруженного вами корневого сертификата.
Итак,
1./path/to/digicert.crt - это файл, который вы только что загрузили.
2./path/to/cacerts - это в вашем пути JRE. Я "нахожу/-name cacerts -print", это поможет вам быстро найти все java-cacerts в вашей файловой системе. Для меня это было/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/security/cacerts
Ответ 4
Взгляните на следующую статью: http://stilius.net/java/java_ssl.php
Он содержит пример кода, который может помочь в случае, если вы пытаетесь получить доступ к вашему script из кода.
Обратите внимание, что вы либо должны использовать системные свойства
javax.net.ssl.keyStore
javax.net.ssl.keyStorePassword
передать сертификат SSL в JVM или импортировать его в хранилище JRE с помощью keytool tool
Ответ 5
Я выяснил, что для обеспечения максимальной безопасности/действительности я должен импортировать сертификат SSL
Нет, нет. Этот шаг вам нужен только в том случае, если ваши клиенты еще не доверяют подписчику сертификата сервера, который возникает только в том случае, если сертификат сервера подписан сам по себе или подписан, например. внутренним СА.
Ответ 6
Эта статья содержит код для изменения пароля доверенного хранилища и добавления туда других сертификатов:
thetechawesomeness.ideasmatter.info