2013-09-25 1 views
1

мне нужно игнорировать здание за исключением PKIX PathИгнорировать SSLHandshakeException только для одного конкретного сервера

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: 
PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderExc 
ption: unable to find valid certification path to requested target 

Я знаю, как сделать это, написав свой собственный класс реализации X509TrustManager, где я всегда return true от isServerTrusted.

Но это довольно широкий. Мой код будет частью более крупного проекта. Я не хочу, чтобы все остальное повлияло на мою замену доверительного менеджера.

Я всегда собираюсь подключиться к фиксированному доменному имени i.e. "www.myws.com". Я хочу только игнорировать SSLHandshakeException только для подключения к «www.myws.com».

Возможно ли это как можно?

+0

возможно дубликат [Реализация X509TrustManager - проходя по части проверки на существующей проверяющего ] (http://stackoverflow.com/questions/19005318/implementing-x509trustmanager-passing-on-part-of-the-verification-to-existing) – Bruno

+0

Это * очень * похоже на ваш другой вопрос, но, похоже, фокусируется подробнее о том, как настроить диспетчер доверия для lar соединение. Какие библиотеки вы используете? – Bruno

+0

@Bruno Это похоже на мой другой вопрос. Но, конечно, не дубликат. Приближается одна и та же проблема от 2-х разностных углов. Исключение SSL возникает, когда доменное имя не соответствует теме в сертификате. Здесь я пытаюсь фильтровать на основе Domain Name, там я пытаюсь фильтровать на основе темы. Существует мало шансов, что ответы на 2 вопроса будут одинаковыми, потому что я не думаю, что TrustManager получает доменное имя сервера вообще. Я думаю, что сравнение доменных имен произойдет до (или после), чтобы TrustManager попросил проверить, подписан ли сертификат доверенным ЦС. – user93353

ответ

0

Существует мало шансов, что ответы на 2 вопроса будут одинаковыми, поскольку я не думаю, что TrustManager получает доменное имя сервера вообще.

Фактически, менеджер доверия может получить имя имени хоста, которым вы были. Однако это зависит от ряда факторов.

  • Давайте предположим, что ваши клиенты работают на Java 7.

    Если вы будете следовать тот же метод, что и в this other answer, но использовать X509ExtendedTrustManager (введен в Java 7, в отличие от обычного X509TrustManager), вам 'll получить дополнительные перегруженные методы, которые дают вам текущий SSLSocket или SSLEngine.

    SSLContext использует эти методы, когда инициализируется с X509ExtendedTrustManager, например, но не тогда, когда это простой X509TrustManager, поэтому он должен проверять тип, прежде чем принимать эти вызовы (см быстрый тест в конце этого ответа, базы на the code in that answer).

    Я не уверен, где это поведение указано API. Там нет ничего об этом X509ExtendedTrustManager тип-check в JSSE Reference Guide. Одним из способов обеспечения использования расширенных методов является установка enpoint identification algorithm (like HTTPS) in your SSLParameters, но вам потребуется определенный контроль над клиентским кодом и библиотеками, которые он использует. (Это также функция, представленная в Java 7.)

    Из SSLSocket или SSLEngine полученных там, вы можете получить и равноправный узел SSLSession, чтобы вы могли выполнить проверку там. (Обратите внимание, что имя хоста может не соответствовать тому, что было предназначено, если библиотека, создающая или SSLEngine, не использовала один из методов, который передает это имя как String, но вместо этого передал InetAddress. Вы также потеряете SNI в этот случай.)

    Тогда вы можете использовать такой менеджер доверия по умолчанию SSLContextsetDefault(...)).

  • Если вы не хотите влиять на значение по умолчанию SSLContext (разумный выбор для такого рода настройки), вам нужно выяснить, как ваша клиентская библиотека может использовать другую для каждого подключения. Это полностью зависит от того, что используется.

    Для традиционного URLConnection, брось как HttpsURLConnection и установить это SSLSocketFactory, как один из сборки пользовательских SSLContext.


Какие методы используются будет зависеть от того, находятся ли создан экземпляр X509ExtendedTrustManager или X509TrustManager:

X509TrustManager customTm = new X509ExtendedTrustManager() { 
    @Override 
    public X509Certificate[] getAcceptedIssuers() { 
     return finalTm.getAcceptedIssuers(); 
    } 

    @Override 
    public void checkServerTrusted(X509Certificate[] chain, 
      String authType) throws CertificateException { 
     System.out 
       .println("Current method: checkServerTrusted(chain, authType)"); 
     finalTm.checkServerTrusted(chain, authType); 
    } 

    //@Override 
    public void checkServerTrusted(X509Certificate[] chain, 
      String authType, Socket socket) throws CertificateException { 
     System.out 
       .println("Current method: checkServerTrusted(chain, authType, socket)"); 
     finalTm.checkServerTrusted(chain, authType, socket); 
    } 

    //@Override 
    public void checkServerTrusted(X509Certificate[] chain, 
      String authType, SSLEngine engine) 
      throws CertificateException { 
     System.out 
       .println("Current method: checkServerTrusted(chain, authType, engine)"); 
     finalTm.checkServerTrusted(chain, authType, engine); 
    } 

    // Same for client-related methods. 
};