2015-10-27 24 views
17

Sembra che Java 6 supporti TLS fino alla versione 1.0, esiste un modo per utilizzare TLS 1.2 in Java 6?Come utilizzare TLS 1.2 in Java 6

Forse una patch o un particolare aggiornamento di Java 6 avranno supporto per questo?

+0

Java 6 è anche bloccato a moduli DH a 1024 bit, IIRC. Dopo [logjam] (http://stackoverflow.com/a/30706878), probabilmente non sarà in grado di connettersi a un server ben configurato. Se possibile, dovresti probabilmente passare ad un'altra piattaforma client. – jww

+0

Attualmente, Java 6 e 7 supportano ora i tasti effimeri DH fino a 2048 bit, a cominciare da JRE 6U105 (aka1.6.0_105) e 7u91 (ovvero 1.7.0_91). (Fonte: https://github.com/mozilla/server-side-tls/issues/107) –

risposta

14

Le versioni Oracle Oracle 6 pubbliche non supportano TLSv1.2. Potrebbero essere rilasciate versioni a pagamento di Java 6 (post-EOL). (UPDATE - TLSv1.1 è disponibile per Java 1.6 dall'aggiornamento 111 in poi; source)

Contattare le vendite di Oracle.

Altre alternative sono:


Tuttavia, vorrei consigliare l'aggiornamento a una Java 8. Java 6 è stato EOL'd nel febbraio 2013 e di continuare ad utilizzarla è potenzialmente rischioso. (Dillo o ricorda il capo/il cliente. Devono saperlo.)

+1

Una nota a riguardo. Tutti gli esempi che ho visto usando Bouncy sono basati sull'invio di comandi HTTP non elaborati ... È un po 'difficile integrare in un programma di lavoro/produzione. Ovviamente, il modo migliore sarebbe aggiornare la JVM (a seconda del server di applicazione, IBM JVM, f.e, non potrebbe essere disponibile ... in un ambiente Oracle WLS). Di seguito spiegherò una soluzione alternativa, semplicemente utilizzando un SocketConnectionFactory SSL personalizzato basato su Bouncy. Se qualcuno ha trovato una soluzione, basandosi non solo sui comandi HTTP raw sendind, per favore condividete per i procommons ..! .-) – Azimuts

3

È necessario creare il proprio SSLSocketFactory basato su Bouncy Castle. Dopo averlo utilizzato, passa alla HttpsConnextion comune per l'utilizzo di SocketFactory personalizzato.

1. In primo luogo: Creare un TLSConnectionFactory

Ecco uno punte:

1.1 Estendere SSLConnectionFactory

1.2 ignorare questo metodo:

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

Questo metodo chiamerà il prossimo metodo interno,

1.3 Implementare un metodo interno _createSSLSocket (host, tlsClientProtocol);

Qui è necessario creare un socket utilizzando TlsClientProtocol. Il trucco è di override ... metodo startHandshake() chiamando TlsClientProtocol

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

Importante: Il campione completo come utilizzare TLS client protocollo è ben spiegato qui: Using BouncyCastle for a simple HTTPS query

2. Secondo: Utilizzare questo Customized SSLConnextionFactory su HTTPSConnection comune.

Questo è importante! In altri esempi puoi vedere nel web, vedi comandi HTTP hard-coded .... quindi con un SSLConnectionFactory personalizzato non hai bisogno di altro ...

URL myurl = new URL("http:// ...URL tha only Works in TLS 1.2); 
    HttpsURLConnection con = (HttpsURLConnection)myurl.openConnection(); 
    con.setSSLSocketFactory(new TSLSocketConnectionFactory()); 
+0

grazie. sto usando bouncyCastle in Tomcat. potresti spiegare la soluzione in dettaglio? o c'è qualche esempio o tutorial in personalizzare BC per usare TLS1.2 (in java6)? – alex

+0

I campioni completi si trovano in questo uri: http://stackoverflow.com/questions/8171802/using-bouncycastle-for-a-simple-https-query – Azimuts

+0

Ma ... provare a implementare un SSLConnectionFactory personalizzato (TLSConnectionFactory), in il modo in cui spiego ... Iniziare a creare una classe che estenda SSLConnectionFactory e sovrascrivi @Override public Socket createSocket (socket socket, host String finale, porta int, booleano arg3) ... Proprio lì chiama il TSLClientProtocol – Azimuts

5

Ecco un TLSConnection fabbrica:

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 

    } 
} 
+1

Se preferisci puoi usare i comandi HTTP grezzi in questo modo http://stackoverflow.com/questions/8171802/using-bouncycastle-for-a-simple-https-query?lq=1 ..... Ma sono grezzi http comandi .... Penso che sia meglio usare HTTPSUrlconnection + personalizzato SSLConnectionFactory: URL myurl = nuovo URL ("http: // ... URL che funziona solo in TLS 1.2); HttpsURLConnection con = (HttpsURLConnection) myurl.openConnection(); con.setSSLSocketFactory (nuovo TSLSocketConnectionFactory()); – Azimuts

+0

Sono bloccato con Java 5 e questa sembra essere l'unica soluzione. Vedo che molti di questi metodi sono vuoti, genera eccezioni o restituisce valori null. questo? hai un'implementazione di fabbrica di connessione TLS funzionante? – Saky

7

Java 6, ora supporta TLS 1.2, controllare qui di seguito

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

+2

Sebbene ciò possa teoricamente rispondere alla domanda, [sarebbe preferibile] (// meta.stackoverflow.com/q/8259) includere qui le parti essenziali della risposta e fornire il link per riferimento. –

+2

Sembra che questa versione sia disponibile solo per coloro che hanno un contratto di supporto. – user872858