Сертификаты Java и SSL
Я пытаюсь установить соединение с моим PHP-скриптом на Java с использованием уровня защищенных сокетов (HTTPS), но я обнаружил, что для обеспечения максимальной безопасности / достоверности я должен импортировать сертификат SSL, который мой веб-сайт использует в моем приложении... Что-то, что я не знаю, как сделать.
Если это помогает, мой SSL-сертификат не является самоподписанным, скорее предоставляется StartSSL, и я использую Eclipse IDE.
Кто-нибудь может указать мне правильное направление? т.е. какие файлы мне нужны, куда я должен их импортировать и какой код мне нужен в Java и т. д.?
5 ответов
Я обнаружил, что для обеспечения максимальной безопасности / действительности я должен импортировать сертификат SSL, который мой веб-сайт использует в моем приложении
Вы частично правы, когда делаете это заявление. Вам не нужно импортировать сертификат SSL. Достаточно импортировать сертификат CA StartSSL.
Кроме того, нет такой вещи, как импорт сертификата в приложение Java. Поддержка SSL в Java основана на концепции хранилищ ключей и доверенных сертификатов, а не на каком-то сертификате, упакованном в вашем приложении. Если вы публикуете свое приложение для загрузки и выполнения конечными пользователями, вам не нужно публиковать свой сертификат или, в этом случае, свой личный ключ в своем приложении. Закрытый ключ и связанный с ним сертификат будут храниться в хранилище ключей, к которому имеют доступ только вы.
Конечные пользователи вашего приложения будут полагаться на поддержку SSL во время выполнения Java, что позволит приложению устанавливать SSL-соединения с сайтами после проверки сертификата сервера. Среда выполнения Java поставляется с набором сертификатов CA по умолчанию в хранилище доверенных сертификатов, и единственным условием успешного установления SSL-соединений является выдача SSL-сертификата сервера одним из CA в хранилище доверенных сертификатов. Сертификаты 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.
Следующий метод загружает хранилище ключей по умолчанию (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's 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's 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"));
Очевидно, что инженеры почтовых пушек по какой-то причине не хотят давать нам четкие инструкции о том, как решить эту проблему. Это то что я сделал
Мы запускаем tomcat8 и подключаемся через веб-сервисы Джерси к API почтового оружия. Я следовал инструкциям этого пользователя, и он работал нормально. Надеюсь, это кому-нибудь поможет.
1/22 мы обновили наши SSL-сертификаты, поскольку инфраструктура PKI Symantec стала ненадежной. Некоторые старые версии 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 и расположение корневого сертификата, который вы скачали.
Итак, 1. /path/to/digicert.crt - это файл, который вы только что скачали. 2. / путь / к / cacerts - это ваш путь JRE. Я "найду / -name cacerts -print", это поможет вам быстро найти все java cacerts в вашей файловой системе. Для меня это был /usr/lib/jvm/java-7-openjdk-amd64/jre/lib/security/cacerts
Взгляните на следующую статью: http://stilius.net/java/java_ssl.php Содержит пример кода, который может помочь в случае, если вы пытаетесь получить доступ к вашему сценарию из кода.
Обратите внимание, что вы либо должны использовать системные свойства
javax.net.ssl.keyStore
javax.net.ssl.keyStorePassword
передать SSL-сертификат в JVM или импортировать его в хранилище ключей JRE с помощью инструмента keytool
Эта статья содержит код для изменения пароля доверенного хранилища и добавления туда других сертификатов:
http://thetechawesomeness.ideasmatter.info/changing-trust-store-password.html
Я обнаружил, что для обеспечения максимальной безопасности / действительности я должен импортировать сертификат SSL
Нет, ты не Этот шаг необходим только в том случае, если ваши клиенты еще не доверяют подписавшему сертификат сервера, который возникает, только если сертификат сервера самоподписан или подписан, например, внутренним центром сертификации.