Сертификаты 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