2017-08-25 8 views
1

J'utilise Retrofit et OkHttp3 pour faire des demandes. Je comprends que dans Android 4.4 TLS 1.1 et TLS 1.2 ne sont pas activés par defult. Donc j'essaie de les activer. Mais jusqu'à présent, je n'avais aucun succès. Je lis que cela pourrait être un problème de l'émulateur studio android, mais je ne peux pas faire un test sur un véritable appareil avec Andoroid 4.4 rigthnowActiver TLS 1.2 dans Android 4.4

C'est ce que je l'ai fait jusqu'à présent:

private <S> S createService(Class<S> serviceClass) { 
    Retrofit retrofit = builder.client(getNewHttpClient()).build(); 
    return retrofit.create(serviceClass); 
} 

private OkHttpClient getNewHttpClient() { 
    OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder() 
      .connectTimeout(10, TimeUnit.SECONDS) 
      .writeTimeout(10, TimeUnit.SECONDS) 
      .readTimeout(0, TimeUnit.MINUTES); // Disable timeouts for read 

    return enableTls12OnPreLollipop(clientBuilder).build(); 
} 


public static OkHttpClient.Builder enableTls12OnPreLollipop(OkHttpClient.Builder client) { 
    if (Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) { 
     try { 
      client.sslSocketFactory(new TLSSocketFactory()); 

      ConnectionSpec cs = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS) 
        .tlsVersions(TlsVersion.TLS_1_2) 
        .build(); 

      List<ConnectionSpec> specs = new ArrayList<>(); 
      specs.add(cs); 
      specs.add(ConnectionSpec.COMPATIBLE_TLS); 
      specs.add(ConnectionSpec.CLEARTEXT); 

      client.connectionSpecs(specs); 
     } catch (Exception exc) { 
      Log.e("OkHttpClientProvider", "Error while enabling TLS 1.2", exc); 
     } 
    } 

    return client; 
} 

TLSSocketFactory CLASSE

public class TLSSocketFactory extends SSLSocketFactory { 
private SSLSocketFactory delegate; 

public TLSSocketFactory() throws KeyManagementException, NoSuchAlgorithmException { 
    SSLContext context = SSLContext.getInstance("TLS"); 
    context.init(null, null, null); 
    delegate = context.getSocketFactory(); 
} 

@Override 
public String[] getDefaultCipherSuites() { 
    return delegate.getDefaultCipherSuites(); 
} 

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

@Override 
public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException { 
    return enableTLSOnSocket(delegate.createSocket(s, host, port, autoClose)); 
} 

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

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

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

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

private Socket enableTLSOnSocket(Socket socket) { 
    if(socket != null && (socket instanceof SSLSocket)) { 
     ((SSLSocket)socket).setEnabledProtocols(new String[] {"TLSv1.1", "TLSv1.2"}); 
    } 
    return socket; 
} 
} 

J'ai essayé this mais n'a pas fonctionné.

Mon erreur est: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0xb829bae0: Failure in SSL library, usually a protocol error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure (external/openssl/ssl/s23_clnt.c:741 0x8d9e3990:0x00000000)

Répondre

2

S'il vous plaît, essayez ceci: https://developer.android.com/training/articles/security-gms-provider.html.

Il utilise https://developers.google.com/android/reference/com/google/android/gms/security/ProviderInstaller, vous devez avoir l'API Google dans votre projet.

Vous devez simplement appeler dans votre application:

@Override 
public void onCreate() { 
    super.onCreate(); 
    try { 
     ProviderInstaller.installIfNeeded(this); 
    } catch (GooglePlayServicesRepairableException | GooglePlayServicesNotAvailableException e) { 
     e.printStackTrace(); 
    } 
} 

Vous devez également supprimer votre SSLfactory personnalisé.

+0

Je reçois un GooglePlayServicesNotAvailableException .. Cela signifie que je ne peux pas mettre à jour le fournisseur. Peut-être parce que j'utilise l'emultaor qui n'a pas installé Google Play Services? Donc, je dois demander aux utilisateurs qui ne l'ont pas installé à installer, rigth? –

+0

Il pourrait être, bien que le meilleur moyen de savoir est de tester sur un périphérique réel. Je crois que les utilisateurs devraient avoir une boîte de dialogue appropriée pour les rediriger vers GooglePlay. –

2

Cette erreur se produit généralement lorsque Android revient à SSLv3 à partir de TLSv1. C'est un bug dans les dispositifs pré-sucette.

La solution consiste à supprimer SSLv3 en utilisant le fournisseur de sécurité d'Android.

essayer cette solution:

private void updateAndroidSecurityProvider(Activity callingActivity) { 
    try { 
     ProviderInstaller.installIfNeeded(this); 
    } catch (GooglePlayServicesRepairableException e) { 
    GooglePlayServicesUtil.getErrorDialog(e.getConnectionStatusCode(), callingActivity, 0); 
    } catch (GooglePlayServicesNotAvailableException e) { 
     Log.e("SecurityException", "Google Play Services not available."); 
    } 
}