java.net.SocketException: программное обеспечение вызвало прерывание соединения: сбой recv при использовании другой безопасности jre

1

Я получаю следующее исключение, пытаясь подключиться к веб-службе, используя HttpsURLConnection, запущенную на хосте в той же сети. Firewall отключен. Интересная часть заключается в том, что если я запустил следующий код через стандартную среду java JRE 1.7 по умолчанию в eclipse, все будет хорошо.

Но если я использую эти функции в коде продукта, который имеет свою собственную папку jre, он выдает следующее исключение -

Caused by: java.net.SocketException: Software caused connection abort: recv failed
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.read(SocketInputStream.java:173)
    at java.net.SocketInputStream.read(SocketInputStream.java:122)
    at com.rsa.sslj.x.aP.c(Unknown Source)
    at com.rsa.sslj.x.aP.a(Unknown Source)
    at com.rsa.sslj.x.aP.a(Unknown Source)
    at com.rsa.sslj.x.aP.h(Unknown Source)
    at com.rsa.sslj.x.cy.startHandshake(Unknown Source)
    at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:563)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1300)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254)

Я заметил, что список поставщиков безопасности отличается в файле java.security.

Вот этот список -

security.provider.1=com.rsa.jsafe.provider.JsafeJCE
security.provider.2=com.rsa.jsse.JsseProvider
security.provider.3=sun.security.provider.Sun
security.provider.4=sun.security.rsa.SunRsaSign
security.provider.5=com.sun.net.ssl.internal.ssl.Provider
security.provider.6=com.sun.crypto.provider.SunJCE
security.provider.7=sun.security.jgss.SunProvider
security.provider.8=com.sun.security.sasl.Provider
security.provider.9=org.jcp.xml.dsig.internal.dom.XMLDSigRI
security.provider.10=sun.security.smartcardio.SunPCSC
security.provider.11=sun.security.mscapi.SunMSCAPI

Это мои функции -

private InputStream Get(URL url,String keyStoreString, String keyStorePassword) {
    SSLSocketFactory sslFactory;
    try {
        sslFactory = getSSLSocketFactory(keyStoreString, keyStorePassword);     
        javax.net.ssl.HttpsURLConnection
                .setDefaultHostnameVerifier(new  javax.net.ssl.HostnameVerifier() {
                    public boolean verify(String hostname,
                            javax.net.ssl.SSLSession sslSession) {
                        if (hostname.equals("vmm")) {
                            return true;
                        }
                        return false;
                    }
                });
        HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
        con.setSSLSocketFactory(sslFactory);
        con.setRequestMethod("GET");
        con.setRequestProperty("Accept", "application/json");
        InputStream responseStream = con.getInputStream();
        return responseStream;
      }catch (Exception e) {
        //log errer
      }
}
private SSLSocketFactory getSSLSocketFactory(String keyStoreString,
        String password) throws KeyStoreException,
        NoSuchAlgorithmException, CertificateException, IOException,
        UnrecoverableKeyException, KeyManagementException, AzureException {
      KeyStore ks = getKeyStore(keyStoreString, password);
      KeyManagerFactory keyManagerFactory = KeyManagerFactory
            .getInstance("SunX509");
      keyManagerFactory.init(ks, password.toCharArray());
      // Trustmanager which trusts all certificate. Not a good idea in
      // production code.
      final TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
        @Override
        public void checkClientTrusted(final X509Certificate[] chain,
                final String authType) {
        }

        @Override
        public void checkServerTrusted(final X509Certificate[] chain,
                final String authType) {
        }

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }
    } };

    SSLContext context = SSLContext.getInstance("TLS");
    context.init(keyManagerFactory.getKeyManagers(), trustAllCerts,
            new SecureRandom());

    return context.getSocketFactory();
}

Мне нужно, чтобы эти функции работали в коде продукта. Любая помощь будет оценена. Заранее спасибо !!

Теги:
security
ssl

2 ответа

0
Лучший ответ

Я явно установил поставщиков для KeyManagerFactory и SSLContext в "SunJSSE", и это сработало!

KeyManagerFactory keyManagerFactory = KeyManagerFactory
            .getInstance("SunX509","SunJSSE");

SSLContext context = SSLContext.getInstance("TLS","SunJSSE");
  • 0
    Это имеет смысл, но зачем вам устанавливать провайдера RSA JSSE в производственной среде и не использовать его (поскольку вы явно форсируете здесь использование провайдера Oracle / Sun JSSE)? Обратите внимание, что ваш верификатор хоста и менеджер доверия тоже небезопасны.
0

Возможно, попытка использовать SunX509 KeyManagerFactory может привести к путанице с другими фабриками за кулисами, когда RSA Jsafe имеет более высокий приоритет, чем поставщик Sun.

Если RSA Jsafe предоставляет собственную реализацию KeyManagerFactory, попробуйте:

KeyManagerFactory keyManagerFactory = 
    KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());

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

  • 0
    Пробовал это. Но не помогите!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню