2015-10-12 66 views
10
Server: 
TLS Version: v1.2 
Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA256 

Client: 
JRE 1.7 

otrzymuję poniżej błąd podczas próby połączenia się z serwerem z Klientem poprzez SSL bezpośrednio:Włącz TLSv1.2 i TLS_RSA_WITH_AES_256_CBC_SHA256 Cipher Suite

Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure 
     at sun.security.ssl.Alerts.getSSLException(Alerts.java:192) 
     at sun.security.ssl.Alerts.getSSLException(Alerts.java:154) 

Poniższy kod umożliwia TLSv1.2

Set<String> enabledTLSSet = new HashSet<String>(Arrays.asList(sslsocket.getEnabledProtocols())); 
    enabledTLSSet.add("TLSv1.2");  
    sslsocket.setEnabledProtocols(enabledTLSSet.toArray(new String[enabledTLSSet.size()])); 

poniższy kod umożliwia TLS_RSA_WITH_AES_256_CBC_SHA256 Cipher Suite:

Set<String> enabledCipherSuitesSet = new HashSet<String>(Arrays.asList(sslsocket.getEnabledCipherSuites())); 
     enabledCipherSuitesSet.add("TLS_RSA_WITH_AES_256_CBC_SHA256"); 
     sslsocket.setEnabledCipherSuites(enabledCipherSuitesSet.toArray(new String[enabledCipherSuitesSet.size()])); 

Po wykonaniu obu powyższych czynności z kodu Java, mogę połączyć się z serwerem z powodzeniem za pośrednictwem protokołu SSL.

Czy można włączyć/wymusić TLSv1.2 i TLS_RSA_WITH_AES_256_CBC_SHA256 w Javie 7 bez zmiany kodu Java przez właściwości, parametry lub rekordy debugowania?

Próbowałem wszystkie poniższe właściwości we wszystkich formach i kombinacjach (włączanie i wyłączanie) i nie powiodło się.

-Dhttps.protocols=TLSv1.2 
-Dhttps.cipherSuites=TLS_RSA_WITH_AES_256_CBC_SHA256 
-Ddeployment.security.TLSv1.2=true 

ja wykonując program podobny do poniżej:

java -jar -Dhttps.protocols=TLSv1.2 -Dhttps.cipherSuites=TLS_RSA_WITH_AES_256_CBC_SHA256 Ddeployment.security.TLSv1.2=true -Djavax.net.debug=ssl:handshake SSLPoker.jar <SERVER> 443 

SSLPoker zawiera poniższy kod:

package com.ashok.ssl; 

import javax.net.ssl.SSLSocket; 
import javax.net.ssl.SSLSocketFactory; 
import java.io.*; 

/** 
* Establish a SSL connection to a host and port, writes a byte and prints the response - Ashok Goli. See 
* http://confluence.atlassian.com/display/JIRA/Connecting+to+SSL+services 
*/ 
public class SSLPoke { 

    /** 
    * The main method. 
    * Usage: $java -jar SSLPoker.jar <host> <port> 
    * 
    * @param args the arguments 
    */ 
    public static void main(String[] args) { 
    if (args.length != 2) { 
     System.out.println("Usage: " + SSLPoke.class.getName() + " <host> <port>"); 
     System.exit(1); 
    } 
    try { 
     SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault(); 
     SSLSocket sslsocket = 
      (SSLSocket) sslsocketfactory.createSocket(args[0], Integer.parseInt(args[1])); 

     InputStream in = sslsocket.getInputStream(); 
     OutputStream out = sslsocket.getOutputStream(); 

     // Write a test byte to get a reaction :) 
     out.write(1); 

     while (in.available() > 0) { 
     System.out.print(in.read()); 
     } 
     System.out.println("Successfully connected"); 

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

Wszelkie wskazówki, jak osiągnąć to bez zmian w kodzie Java będzie być docenionym.

+0

Nie można dodawać zestawów szyfrów TLS bez dodawania całego dostawcy zabezpieczeń, takiego jak Bouncy Castle, który rzeczywiście może go obsługiwać. – EJP

+0

Z jakich ustawień muszę się bawić, aby to osiągnąć? –

+0

Dodałem TLS i pomyślnie nawiązałem połączenie z serwerem za pomocą powyższego kodu. Po prostu szuka sposobu, aby to zrobić poprzez konfigurację. –

Odpowiedz

10

Jest to możliwe tylko w przypadku korzystania z prostego połączenia HTTPS (SSL nie Sockets) przy użyciu właściwości

-Dhttps.protocols=TLSv1.2 
-Dhttps.cipherSuites=TLS_RSA_WITH_AES_256_CBC_SHA256 

Zobacz posta na http://fsanglier.blogspot.com.es/

Java 7 wprowadzono obsługę TLS v1.2 (odnieś się do http://docs.oracle.com/javase/7/docs/technotes/guides/security/enhancements-7.html) BUT nie włącza tego domyślnie. Innymi słowy, Twoja aplikacja klienta musi jawnie określać "TLS v1.2" przy tworzeniu SSLContext, lub inaczej nie będzie w stanie z niego skorzystać.

Jeśli trzeba użyć bezpośrednio bezpiecznego protokołu socket, stworzyć „TLSv1.2” SSLContext podczas uruchamiania aplikacji i używać SSLContext.setDefault I (CTX) zadzwonić do rejestracji tego nowego kontekstu jako domyślny.

SSLContext context = SSLContext.getInstance("TLSv1.2"); 
SSLContext.setDefault(context); 
+0

Wow ... To jest rzeczywiście wymagane. Zauważyłem, że zostały one zignorowane, ale nie oczekiwałem, że serwer będzie już wymagał TLS 1.2 – Kukeltje

3

JRE wyłącza domyślnie wszystkie 256-bitowe krypto. Aby włączyć można pobrać Java Cryptography Extension (JCE) Pliki Polityka Nieograniczona Wytrzymałość Jurysdykcja tutaj: http://www.oracle.com/technetwork/java/javase/downloads/index.html

Wymień local_policy.jar i US_export_policy.jar słoiki pliki do swojego lib/security w katalogu JRE.

+0

To działało idealnie w moim przypadku. –

1

Wygląda na to, że obecny plik JRE zawiera zarówno ograniczone, jak i nielimitowane pliki zasad w folderze instalacyjnym środowiska JRE pod numerem lib/security, każdy w osobnych podkatalogach. Domyślnie w lib/security/java.security domyślnie używana jest zasada limited. Ale jeśli odkomentujesz linię crypto.policy=unlimited, która pozwoli Javy korzystać z plików zasad unlimited i włączyć 256-bitowe szyfry/algorytmy.