Почему мне нужно добавить SSL-сертификат сервера, если моя клиентская программа работает на Java, а не на C #? - PullRequest
2 голосов
/ 17 февраля 2011

Если я использую HttpsURLConnection в программе на Java и пытаюсь открыть URL, начинающийся с https://, я получу сообщение об ошибке:

невозможно найти действительный путь сертификации для запрошенной цели

и решение, которое я нашел, это для добавления сертификата сервера в хранилище сертификатов клиента . Но если я напишу программу на C #, которая использует HttpWebRequest, мне не нужно ничего добавлять.

Так что для меня это выглядит так, как будто клиент C # "просто работает", а клиент Java работает только после настройки молотком.

Почему для клиента Java требуется дополнительный шаг? Можно ли как-то пропустить сохранение сертификата в хранилище клиента JVM?

Ответы [ 4 ]

2 голосов
/ 17 февраля 2011

Я полагаю, это потому, что C # использует тот же HTTP-клиент, что и MSIE, поэтому у него много предустановленных SSL-сертификатов, включая тот, который вы используете. JVM имеет меньше предварительно установленных сертификатов.

2 голосов
/ 17 февраля 2011

HttpWebRequest будет использовать собственное хранилище сертификатов Windows для проверки сертификатов, то есть то же самое, что и IE.Если ваш IE может правильно проверить сертификат, имея сертификат или путь CA обратно к доверенному корню, то HttpWebRequest должен принять сертификат в порядке.

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

1 голос
/ 03 декабря 2014

Хорошим источником информации по этой теме является Усиление безопасности в собственной платформе с использованием технологии Java SE 6 и Справочное руководство по расширению сокетов Java (JSSE) на сайте Oracle.

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

-Djavax.net.ssl.keyStoreType=Windows-MY -Djavax.net.ssl.trustStoreType=Windows-ROOT

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

    KeyStore ks = KeyStore.getInstance("Windows-MY");
    ks.load(null, null);

    KeyStore ts = KeyStore.getInstance("Windows-ROOT");
    ts.load(null, null);

    TrustManagerFactory tmf = TrustManagerFactory
                .getInstance(TrustManagerFactory.getDefaultAlgorithm());
    tmf.init(ts);

    KeyManagerFactory kmf = KeyManagerFactory
                .getInstance(KeyManagerFactory.getDefaultAlgorithm());
    kmf.init(ks, new char[0]);

    SSLContext ctx = SSLContext.getInstance("TLS");
    ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);    

    URL url = new URL("https://some.web.site.org");
    javax.net.ssl.HttpsURLConnection urlConnection = 
            (javax.net.ssl.HttpsURLConnection) url.openConnection();
    urlConnection.setSSLSocketFactory(ctx.getSocketFactory());
    urlConnection.connect();
    try (InputStream in = urlConnection.getInputStream();) {
        byte[] chunk = new byte[1024];
        for (int len; (len = in.read(chunk)) > -1;) {
            System.out.write(chunk, 0, len);
        }
    } finally {
        urlConnection.disconnect();
    }
1 голос
/ 01 августа 2012

По умолчанию Java использует свой собственный набор якорей доверия (в хранилище доверенных сертификатов по умолчанию см. Справочное руководство JSSE ).

Если вы хотите использовать хранилище сертификатов Windows, выможно использовать Windows-ROOT хранилище ключей в качестве хранилища доверия.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...