Как использовать TLS 1.2 в Java 6

Кажется, что Java 6 поддерживает TLS до версии 1.0, есть ли способ использовать TLS 1.2 в Java 6?

Может быть, патч или конкретное обновление Java 6 будет его поддерживать?


person alex    schedule 27.10.2015    source источник
comment
Java 6 также застревает на 1024-битных модулях DH, IIRC. После logjam он, вероятно, не сможет подключиться к хорошо настроенному серверу. Если возможно, вам, вероятно, следует перейти на другую клиентскую платформу.   -  person jww    schedule 07.11.2016
comment
Фактически, Java 6 и 7 теперь поддерживают эфемерные ключи DH длиной до 2048 бит, начиная с JRE 6U105 (он же 1.6.0_105) и 7u91 (он же 1.7.0_91). (Источник: github.com/mozilla/server-side-tls/issues/107)   -  person Stephen C    schedule 05.03.2018


Ответы (8)


Публичные выпуски Oracle Java 6 не поддерживают TLSv1.2. Платные выпуски Java 6 (после EOL) могут. (ОБНОВЛЕНИЕ - TLSv1.1 доступен для Java 1.6 начиная с обновления 111; источник)

Обратитесь в отдел продаж Oracle.

Другие альтернативы:

  • Используйте альтернативную реализацию JCE, например Bouncy Castle. См. этот ответ, чтобы узнать, как это сделать. Он изменяет реализацию по умолчанию SSLSocketFactory, так что ваше приложение будет прозрачно использовать BC. (В других ответах показано, как явно использовать реализацию BC SSLSocketFactory, но этот подход повлечет за собой изменение кода приложения или библиотеки, открывающего сокеты.)

  • # P5 #
    # P6 #

Однако я бы посоветовал перейти на Java 11 (сейчас). Java 6 была прекращена в феврале 2013 года, и дальнейшее ее использование потенциально рискованно. Бесплатная Oracle Java 8 является EOL для многих случаев использования. (Скажите или напомните начальнику / клиенту. Им нужно знать.)

person Stephen C    schedule 27.10.2015
comment
Одно замечание об этом. Все образцы, которые я видел с помощью Bouncy, основаны на отправке сырых HTTP-команд ... Это немного сложно интегрировать в рабочую / производственную программу. Очевидно, что лучшим способом было бы обновить JVM (в зависимости от сервера приложений, IBM JVM, например, может быть недоступна .. в среде Oracle WLS). Ниже я объясняю обходной путь, просто используя настроенную SSL SocketConnectionFactory на основе Bouncy. Если кто-то нашел решение, основанное не только на отправке необработанных HTTP-команд, поделитесь, пожалуйста, с советами ..! .-) - person Azimuts; 28.10.2015

После нескольких часов игры с Oracle JDK 1.6 я смог заставить его работать без каких-либо изменений кода. Магия выполняется Bouncy Castle для обработки SSL и позволяет JDK 1.6 работать с TLSv1.2 по умолчанию. Теоретически его также можно применить к более старым версиям Java с возможными корректировками.

  1. Загрузите последнюю версию Java 1.6 с веб-сайта Java Archive Oracle < / а>
  2. Распакуйте его по предпочтительному пути и установите переменную среды JAVA_HOME.
  3. Обновите JDK последней версией Java Cryptography Extension (JCE), файлов политики юрисдикции с неограниченной надежностью 6
  4. Загрузите файлы Bounce Castle bcprov-jdk15to18-165.jar и bctls-jdk15to18-165.jar и скопируйте их в свою ${JAVA_HOME}/jre/lib/ext папку
  5. Измените файл ${JAVA_HOME}/jre/lib/security/java.security, закомментировав раздел провайдеров и добавив несколько дополнительных строк.
    # Original security providers (just comment it)
    # security.provider.1=sun.security.provider.Sun
    # security.provider.2=sun.security.rsa.SunRsaSign
    # security.provider.3=com.sun.net.ssl.internal.ssl.Provider
    # security.provider.4=com.sun.crypto.provider.SunJCE
    # security.provider.5=sun.security.jgss.SunProvider
    # security.provider.6=com.sun.security.sasl.Provider
    # security.provider.7=org.jcp.xml.dsig.internal.dom.XMLDSigRI
    # security.provider.8=sun.security.smartcardio.SunPCSC

    # Add the Bouncy Castle security providers with higher priority
    security.provider.1=org.bouncycastle.jce.provider.BouncyCastleProvider
    security.provider.2=org.bouncycastle.jsse.provider.BouncyCastleJsseProvider
    
    # Original security providers with different priorities
    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

    # Here we are changing the default SSLSocketFactory implementation
    ssl.SocketFactory.provider=org.bouncycastle.jsse.provider.SSLSocketFactoryImpl

Чтобы убедиться, что он работает, давайте создадим простую программу на Java для загрузки файлов с одного URL-адреса с использованием https.

import java.io.*;
import java.net.*;


public class DownloadWithHttps {

    public static void main(String[] args) {
        try {
            URL url = new URL(args[0]);
            System.out.println("File to Download: " + url);
            String filename = url.getFile();
            File f = new File(filename);
            System.out.println("Output File: " + f.getName());
            BufferedInputStream in = new BufferedInputStream(url.openStream());
            FileOutputStream fileOutputStream = new FileOutputStream(f.getName());
            int bytesRead;
            byte dataBuffer[] = new byte[1024];

            while ((bytesRead = in.read(dataBuffer, 0, 1024)) != -1) {
                fileOutputStream.write(dataBuffer, 0, bytesRead);
            }
            fileOutputStream.close();

        } catch (Exception ex) {
            ex.printStackTrace();
        }

    }
}

Теперь просто скомпилируйте программу DownloadWithHttps.java и запустите ее со своим Java 1.6.


${JAVA_HOME}/bin/javac DownloadWithHttps.java
${JAVA_HOME}/bin/java DownloadWithHttps https://repo1.maven.org/maven2/org/apache/commons/commons-lang3/3.10/commons-lang3-3.10.jar

Важное примечание для пользователей Windows. Это решение было протестировано в ОС Linux. Если вы используете Windows, замените ${JAVA_HOME} на %JAVA_HOME%.

person Wellington Souza    schedule 09.04.2020
comment
Я использую 64-разрядную версию Java JDK 6u45. Как решить проблему со случайным источником? Просмотрите трассировку стека: C: \ ›java DownloadWithHttps 07.03.2020 13:15:35 07.03.2020 13:15:36 org.bouncycastle.jsse.provider.ProvTrustManagerFactorySpi getDefaultTrustStore ИНФОРМАЦИЯ: Инициализация с хранилищем доверенных сертификатов в путь: C: \ Desenvolvimento \ Ferramentas \ JDKs \ JDK6 \ jre \ lib \ security \ cacerts Исключение в основном потоке java.lang.InternalError: невозможно открыть случайный источник в org.bouncycastle.jcajce.provider.drbg.DRBG $ URLSeeded $ 1SecureRand .run (неизвестный источник) - person cviniciusm; 03.07.2020
comment
Я только что протестировал Windows 10, и он также загружает файл из репозитория maven, как в примере. Пожалуйста, не пропускайте ни один шаг, особенно шаг номер 3. Файлы политики юрисдикции с неограниченной надежностью Java Cryptography Extension (JCE) 6. И если это еще не сработало, вы можете попытаться подделать безопасный случайный случай в Windows, передав параметр JVM через командная строка: -Djava.security.egd=file:/dev/./urandom (обратите внимание на дополнительный ./) - person Wellington Souza; 06.07.2020
comment
Спасибо! У меня это сработало! В моем случае я компилировал проект с java 6 и maven 3.2.5, и при загрузке из центрального репозитория maven возникала ошибка Received fatal alert: protocol_version из-за того, что TLS 1.2 не использовался. - person Afaria; 20.10.2020
comment
Это решение отлично сработало для меня, просто выполнил шаги и все. - person Harshal; 16.11.2020

Java 6, теперь поддерживает TLS 1.2, см. Ниже

http://www.oracle.com/technetwork/java/javase/overview-156328.html#R160_121

person David    schedule 10.10.2016
comment
Хотя теоретически это может дать ответ на вопрос, было бы предпочтительнее включить сюда основные части ответа и предоставить ссылку для справки. . - person Bhargav Rao; 10.10.2016
comment
Похоже, эта версия доступна только тем, у кого есть контракт на поддержку. - person user872858; 07.09.2017

Вот фабрика TLSConnection:

package test.connection;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.Principal;
import java.security.SecureRandom;
import java.security.Security;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.util.Hashtable;
import java.util.LinkedList;
import java.util.List;

import javax.net.ssl.HandshakeCompletedEvent;
import javax.net.ssl.HandshakeCompletedListener;
import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSessionContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.security.cert.X509Certificate;

import org.bouncycastle.crypto.tls.Certificate;
import org.bouncycastle.crypto.tls.CertificateRequest;
import org.bouncycastle.crypto.tls.DefaultTlsClient;
import org.bouncycastle.crypto.tls.ExtensionType;
import org.bouncycastle.crypto.tls.TlsAuthentication;
import org.bouncycastle.crypto.tls.TlsClientProtocol;
import org.bouncycastle.crypto.tls.TlsCredentials;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

/**
 * This Class enables TLS V1.2  connection based on BouncyCastle Providers.
 * Just to use: 
 * URL myurl = new URL( "http:// ...URL tha only Works in TLS 1.2);
   HttpsURLConnection  con = (HttpsURLConnection )myurl.openConnection();
   con.setSSLSocketFactory(new TSLSocketConnectionFactory());  
 * @author AZIMUTS
 *
 */
public class TSLSocketConnectionFactory extends SSLSocketFactory {  


//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Adding Custom BouncyCastleProvider
/////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
   static {
    if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null)
        Security.addProvider(new BouncyCastleProvider());
    }   
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//HANDSHAKE LISTENER
/////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
    public class TLSHandshakeListener implements HandshakeCompletedListener {
        @Override
        public void handshakeCompleted(HandshakeCompletedEvent event) { 

        }
    }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//SECURE RANDOM
/////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
    private SecureRandom _secureRandom = new SecureRandom();

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Adding Custom BouncyCastleProvider
/////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
    @Override
    public Socket createSocket(Socket socket, final String host, int port, boolean arg3)
            throws IOException {
        if (socket == null) {
            socket = new Socket();
        }
        if (!socket.isConnected()) {
            socket.connect(new InetSocketAddress(host, port));
        }

        final TlsClientProtocol tlsClientProtocol = new TlsClientProtocol(socket.getInputStream(), socket.getOutputStream(), _secureRandom);
        return _createSSLSocket(host, tlsClientProtocol);


      }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SOCKET FACTORY  METHODS  
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    @Override
    public String[] getDefaultCipherSuites() {      
        return null;
    }

    @Override
    public String[] getSupportedCipherSuites(){ 
        return null;
    }

    @Override
    public Socket createSocket(String host, int port) throws IOException,UnknownHostException{  
        return null;
    }

    @Override
    public Socket createSocket(InetAddress host, int port) throws IOException { 
        return null;
    }

    @Override
    public Socket createSocket(String host, int port, InetAddress localHost,
            int localPort) throws IOException, UnknownHostException {   
        return null;
    }

    @Override
    public Socket createSocket(InetAddress address, int port,
            InetAddress localAddress, int localPort) throws IOException{    
        return null;
    }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//SOCKET CREATION
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    private SSLSocket _createSSLSocket(final String host , final TlsClientProtocol tlsClientProtocol) {
     return new SSLSocket() {            
        private java.security.cert.Certificate[] peertCerts;

         @Override
          public InputStream getInputStream() throws IOException {
              return tlsClientProtocol.getInputStream();
          }

          @Override
          public OutputStream getOutputStream() throws IOException {
              return tlsClientProtocol.getOutputStream();
          }

          @Override
          public synchronized void close() throws IOException {         
             tlsClientProtocol.close();
          }

           @Override
           public void addHandshakeCompletedListener(HandshakeCompletedListener arg0) {         

           }

            @Override
            public boolean getEnableSessionCreation() {         
                return false;
            }

            @Override
            public String[] getEnabledCipherSuites() {          
                return null;
            }

            @Override
            public String[] getEnabledProtocols() {
                // TODO Auto-generated method stub
                return null;
            }

            @Override
            public boolean getNeedClientAuth(){         
                return false;
            }

            @Override
            public SSLSession getSession() {
                   return new SSLSession() {

                    @Override
                    public int getApplicationBufferSize() {                 
                        return 0;
                    }

                    @Override
                    public String getCipherSuite() {
                         throw new UnsupportedOperationException();
                    }

                    @Override
                    public long getCreationTime() {
                         throw new UnsupportedOperationException();
                    }

                    @Override
                    public byte[] getId() {
                         throw new UnsupportedOperationException();
                    }

                    @Override
                    public long getLastAccessedTime() {
                         throw new UnsupportedOperationException();
                    }

                    @Override
                    public java.security.cert.Certificate[] getLocalCertificates() {
                         throw new UnsupportedOperationException();
                    }

                    @Override
                    public Principal getLocalPrincipal() {
                         throw new UnsupportedOperationException();
                    }

                    @Override
                    public int getPacketBufferSize() {
                         throw new UnsupportedOperationException();
                    }

                    @Override
                    public X509Certificate[] getPeerCertificateChain()
                            throws SSLPeerUnverifiedException {
                        // TODO Auto-generated method stub
                        return null;
                    }

                    @Override
                    public java.security.cert.Certificate[] getPeerCertificates()throws SSLPeerUnverifiedException {
                         return peertCerts;
                    }

                    @Override
                    public String getPeerHost() {
                         throw new UnsupportedOperationException();
                    }

                    @Override
                    public int getPeerPort() {                      
                        return 0;
                    }

                    @Override
                    public Principal getPeerPrincipal() throws SSLPeerUnverifiedException {
                      return null;
                         //throw new UnsupportedOperationException();

                    }

                    @Override
                    public String getProtocol() {
                         throw new UnsupportedOperationException();
                    }

                    @Override
                    public SSLSessionContext getSessionContext() {
                         throw new UnsupportedOperationException();
                    }

                    @Override
                    public Object getValue(String arg0) {
                         throw new UnsupportedOperationException();
                    }

                    @Override
                    public String[] getValueNames() {
                         throw new UnsupportedOperationException();
                    }

                    @Override
                    public void invalidate() {
                         throw new UnsupportedOperationException();

                    }

                    @Override
                    public boolean isValid() {
                         throw new UnsupportedOperationException();
                    }

                    @Override
                    public void putValue(String arg0, Object arg1) {
                         throw new UnsupportedOperationException();

                    }

                    @Override
                    public void removeValue(String arg0) {
                         throw new UnsupportedOperationException();

                    }

                   };
            }


            @Override
            public String[] getSupportedProtocols() {       
                return null;
            }

            @Override
            public boolean getUseClientMode() {             
                return false;
            }

            @Override
            public boolean getWantClientAuth() {

                return false;
            }

            @Override
            public void removeHandshakeCompletedListener(HandshakeCompletedListener arg0) {             

            }

            @Override
            public void setEnableSessionCreation(boolean arg0) {


            }

            @Override
            public void setEnabledCipherSuites(String[] arg0) {         

            }

            @Override
            public void setEnabledProtocols(String[] arg0) {


            }

            @Override
            public void setNeedClientAuth(boolean arg0) {           

            }

            @Override
            public void setUseClientMode(boolean arg0) {            

            }

            @Override
            public void setWantClientAuth(boolean arg0) {               

            }

            @Override
            public String[] getSupportedCipherSuites() {            
                return null;
            }
            @Override
            public void startHandshake() throws IOException {
                  tlsClientProtocol.connect(new DefaultTlsClient() {                       
                         @Override
                          public Hashtable<Integer, byte[]> getClientExtensions() throws IOException {
                                Hashtable<Integer, byte[]> clientExtensions = super.getClientExtensions();
                                if (clientExtensions == null) {
                                    clientExtensions = new Hashtable<Integer, byte[]>();
                                }

                                //Add host_name
                                byte[] host_name = host.getBytes();

                                final ByteArrayOutputStream baos = new ByteArrayOutputStream();
                                final DataOutputStream dos = new DataOutputStream(baos);
                                dos.writeShort(host_name.length + 3); // entry size
                                dos.writeByte(0); // name type = hostname
                                dos.writeShort(host_name.length);
                                dos.write(host_name);
                                dos.close();
                                clientExtensions.put(ExtensionType.server_name, baos.toByteArray());
                                return clientExtensions;
                        }

                        @Override
                        public TlsAuthentication getAuthentication()
                                throws IOException {
                            return new TlsAuthentication() {


                                @Override
                                public void notifyServerCertificate(Certificate serverCertificate) throws IOException {

                                  try {
                                        CertificateFactory cf = CertificateFactory.getInstance("X.509");
                                        List<java.security.cert.Certificate> certs = new LinkedList<java.security.cert.Certificate>();
                                        for ( org.bouncycastle.asn1.x509.Certificate c : serverCertificate.getCertificateList()) {                                          
                                            certs.add(cf.generateCertificate(new ByteArrayInputStream(c.getEncoded())));
                                        }
                                        peertCerts = certs.toArray(new java.security.cert.Certificate[0]);
                                    } catch (CertificateException e) {                                   
                                       System.out.println( "Failed to cache server certs"+ e);
                                       throw new IOException(e);
                                    }

                                }

                                @Override
                                public TlsCredentials getClientCredentials(CertificateRequest arg0)
                                        throws IOException {                                    
                                    return null;
                                }

                            };

                        }

                   });



            }




     };//Socket

    }
}

Помните, что чтобы доказать это, лучше всего протестировать веб-сайт, который предоставляет ТОЛЬКО TLS 1.2. Если Интернет предоставляет TLS 1.0, TLS 1.1 в зависимости от реализации Java будет подключаться с использованием tls 1.0, tls 1.1. Протестируйте его на сайте, который предоставляет только TLS 1.2. Примером может служить защищенный сайт NIST https://www.nist.gov.

person Azimuts    schedule 03.11.2015
comment
Если вы предпочитаете, вы можете использовать необработанные HTTP-команды таким образом stackoverflow.com/questions/8171802/ ..... Но это необработанные HTTP-команды .... Я думаю, что лучше использовать HTTPSUrlconnection + настраиваемый SSLConnectionFactory: URL myurl = new URL (http: // ... URL-адрес, который работает только в TLS 1.2); HttpsURLConnection con = (HttpsURLConnection) myurl.openConnection (); con.setSSLSocketFactory (новый TSLSocketConnectionFactory ()); - person Azimuts; 03.11.2015
comment
Я застрял на Java 5, и это, кажется, единственное решение. Я вижу, что многие из этих методов пусты, выдают исключение или возвращают значения NULL. Какая цель за этим? У вас есть работающая реализация фабрики соединений TLS? - person Saky; 13.06.2017
comment
Это сработало, спасибо. Очень ценю ваш ответ, я уже сходил с ума, прежде чем нашел ваше решение. - person Dmytro Pastovenskyi; 25.06.2018
comment
@Azimuts - У нас аналогичная проблема с JDK 1.6u26, и мы пытались использовать это решение, но получили ту же ошибку. Есть идеи, что может быть не так? - person Ankur Raiyani; 27.06.2019
comment
Большое спасибо за это решение plug & play - оно отлично работало в моей среде (Domino 9.0.1FP8). Мне потребовались бы часы / дни, чтобы заставить это работать - спасибо, что сэкономили мне это время. - person xpages-noob; 03.07.2019
comment
Спасатель! Работал как шарм !! - person tarares; 27.09.2019

Вы должны создать свой собственный SSLSocketFactory на основе Bouncy Castle. После его использования перейдите к общему HttpsConnextion для использования этого настроенного SocketFactory.

1. Во-первых: создайте TLSConnectionFactory

Вот один совет:

1.1 Расширение SSLConnectionFactory

1.2 Переопределите этот метод:

@Override 
public Socket createSocket(Socket socket, final String host, int port, boolean arg3)

Этот метод вызовет следующий внутренний метод,

1.3. Реализуйте внутренний метод _createSSLSocket (host, tlsClientProtocol);

Здесь вы должны создать сокет, используя TlsClientProtocol. Уловка состоит в том, чтобы переопределить ... метод startHandshake (), вызывающий TlsClientProtocol.

 private SSLSocket _createSSLSocket(final String host , final TlsClientProtocol tlsClientProtocol) {
     return new SSLSocket() {    
       .... Override and implement SSLSocket methods,  particulary: 
            startHandshake() {
             }    
     }

     

Важно: полный пример использования клиентского протокола TLS хорошо объяснен здесь: Использование BouncyCastle для простого запроса HTTPS

2. Во-вторых: используйте этот настраиваемый SSLConnextionFactory для обычного HTTPSConnection.

Это важно ! В других примерах вы можете заглянуть в Интернет, увидеть жестко запрограммированные HTTP-команды ... так что с настроенным SSLConnectionFactory вам больше ничего не нужно ...

  URL myurl = new URL( "http:// ...URL tha only Works in TLS 1.2);
  HttpsURLConnection  con = (HttpsURLConnection )myurl.openConnection();
  con.setSSLSocketFactory(new TSLSocketConnectionFactory());
person Azimuts    schedule 27.10.2015
comment
благодаря. Я использую bouncyCastle в Tomcat. не могли бы вы подробно объяснить решение? или есть какой-либо образец или учебник по настройке BC для использования TLS1.2 (в java6)? - person alex; 03.11.2015
comment
Полные образцы находятся в этом uri: stackoverflow.com/questions/8171802/ - person Azimuts; 03.11.2015
comment
Но ... попробуйте реализовать настраиваемый SSLConnectionFactory (TLSConnectionFactory), как я объясняю ... Просто начните создавать класс, который расширяет SSLConnectionFactory и переопределяет @Override public Socket createSocket (Socket socket, final String host, int port, boolean arg3) ... Просто вызовите TSLClientProtocol - person Azimuts; 03.11.2015
comment
У меня есть опасения. я не хочу подключаться к серверу в качестве клиента. Я ищу способ, который позволяет мне отвечать клиенту (браузерам) с помощью tls1.2. Другими словами, у меня есть собственное веб-приложение (развернутое в tomcat), написанное java6 и использующее bouncycastle для ответа на защищенные соединения. но я хочу обновить TLSv1 (который поддерживает) до TLSv1.2 без обновления версии Java. - person alex; 03.11.2015
comment
Ох ... это совсем другое !! , Может быть, вы можете разместить веб-сервер Apache во внешнем интерфейсе (serverfault.com/questions/314858/) для обслуживания tomcat (который можно было поддерживать в jdk 1.6). Извини ._) - person Azimuts; 03.11.2015
comment
спасибо за ваш ответ. это не может решить с bouncyCastle? - person alex; 04.11.2015
comment
Извините, я не знаю ... Может быть, лучше всего было бы использовать apache во внешнем интерфейсе, чтобы вы не зависели от инфраструктуры приложения (Tomcat), но, возможно, это изменение архитектуры, которое нужно измерить. - person Azimuts; 04.11.2015

Если вам нужен доступ к определенному набору удаленных служб, вы можете использовать промежуточный обратный прокси-сервер для выполнения tls1.2 за вас. Это избавит вас от попытки установить патч или обновить java1.6.

например приложение -> прокси: http (5500) [tls-1.2] -> удаленное: https (443)

Конфигурация в простейшей форме (один порт на службу) для apache httpd:

Listen 127.0.0.1:5000
<VirtualHost *:5500>
    SSLProxyEngine On
    ProxyPass / https://remote-domain/
    ProxyPassReverse / https://remote-domain/
</VirtualHost>

Затем вместо доступа к https://remote-domain/ вы получаете доступ к http://localhost:5500/

person Marinos An    schedule 21.01.2019
comment
Спас мой день, не удалось перенести код с Java 6, так что было действительно приятно наткнуться на этот ответ. - person Japheth Odonya; 19.05.2021

Я думаю, что решение @Azimuts (https://stackoverflow.com/a/33375677/6503697) предназначено для HTTP только подключение. Для соединения FTPS вы можете использовать Bouncy Castle с org.apache.commons.net.ftp.FTPSClient без необходимости переписывать протокол FTPS.

У меня есть программа, работающая на JRE 1.6.0_04, и я не могу обновить JRE.

Программа должна подключаться к серверу FTPS, который работает только с TLS 1.2 (сервер IIS).

Я боролся несколько дней и, наконец, понял, что прямо в моем варианте использования есть несколько версий библиотеки bouncy castle: bctls-jdk15on-1.60.jar и bcprov-jdk15on-1.60.jar подходят, но версии 1.64 - нет.

Версия apache commons-net - 3.1.

Ниже приводится небольшой фрагмент кода, который должен работать:

import java.io.ByteArrayOutputStream;
import java.security.SecureRandom;
import java.security.Security;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.commons.net.ftp.FTPSClient;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jsse.provider.BouncyCastleJsseProvider;
import org.junit.Test;


public class FtpsTest {

// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {

    public java.security.cert.X509Certificate[] getAcceptedIssuers() {
        return null;
    }

    public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {
    }

    public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {
    }
} };

@Test public void test() throws Exception {


    Security.insertProviderAt(new BouncyCastleProvider(), 1);
    Security.addProvider(new BouncyCastleJsseProvider());


    SSLContext sslContext = SSLContext.getInstance("TLS", new BouncyCastleJsseProvider());
    sslContext.init(null, trustAllCerts, new SecureRandom());
    org.apache.commons.net.ftp.FTPSClient ftpClient = new FTPSClient(sslContext);
    ByteArrayOutputStream out = null;
    try {

        ftpClient.connect("hostaname", 21);
        if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
            String msg = "Il server ftp ha rifiutato la connessione.";
            throw new Exception(msg);
        }
        if (!ftpClient.login("username", "pwd")) {
            String msg = "Il server ftp ha rifiutato il login con username:  username  e pwd:  password  .";
            ftpClient.disconnect();
            throw new Exception(msg);
        }


        ftpClient.enterLocalPassiveMode();
        ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
        ftpClient.setDataTimeout(60000);
        ftpClient.execPBSZ(0); // Set protection buffer size
        ftpClient.execPROT("P"); // Set data channel protection to private
        int bufSize = 1024 * 1024; // 1MB
        ftpClient.setBufferSize(bufSize);
        out = new ByteArrayOutputStream(bufSize);
        ftpClient.retrieveFile("remoteFileName", out);
        out.toByteArray();
    }
    finally {
        if (out != null) {
            out.close();
        }
        ftpClient.disconnect();

    }

}

}

person Salvatore Iamundo    schedule 11.10.2019
comment
Правильно, спасибо Сальваторе - person Azimuts; 20.11.2019

Я также получил аналогичную ошибку, когда был вынужден использовать TLS1.2 для java 6. И я справился с этим благодаря этой библиотеке:

  1. Клонировать исходный код: https://github.com/tobszarny/ssl-provider-jvm16

  2. Добавить основной класс:

    public static void main(String[] args) throws Exception {
        try {
            String apiUrl = "https://domain/api/query?test=123";
    
            URL myurl = new URL(apiUrl);
            HttpsURLConnection con = (HttpsURLConnection) myurl.openConnection();
            con.setSSLSocketFactory(new TSLSocketConnectionFactory());
            int responseCode = con.getResponseCode();
            System.out.println("GET Response Code :: " + responseCode);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
    
person Tran Hao    schedule 05.10.2020