2017-08-25 34 views
1

私はRetrofitとOkHttp3を使ってリクエストしています。私はAndroid 4.4ではTLS 1.1とTLS 1.2がデフルトによって有効になっていないことを知っていました。だから私はそれらを有効にしようとしている。しかし、これまで私はsucsessを持っていませんでした。私はそれがアンドロイドスタジオエミュレータの問題になることができることを読んで、私はandoroid 4.4と実際のデバイス上でテストをすることはできませんrigthnowAndroid 4.4でTLS 1.2を有効にする

これは私がこれまでにやっていることです:

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 CLASS

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; 
} 
} 

私はthisを試してみましたが、うまくいきませんでした。

私のエラーは、次のとおりです。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)

答えて

2

はこれを試してください:https://developer.android.com/training/articles/security-gms-provider.html

https://developers.google.com/android/reference/com/google/android/gms/security/ProviderInstallerを使用しているため、プロジェクトにGoogle APIが必要です。

あなたは自分のアプリケーションで呼び出す必要があります:

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

ます。また、カスタムSSLfactoryを削除する必要があります。

+0

私は。これは、私はプロバイダを更新しないことを意味GooglePlayServicesNotAvailableExceptionを取得しています:

は、このソリューションを試してみてください。 Google Playサービスをインストールしていないエミュレータを使用している可能性がありますか?だから私はそれをインストールしていないユーザーに、rigthをインストールする必要がありますか? –

+0

実際のデバイスでテストすることが最善の方法ですが、それが可能です。ユーザーはGooglePlayにリダイレクトする適切なダイアログを表示する必要があります。 –

2

このエラーは、通常、アンドロイドがTLSv1からSSLv3に戻ったときに発生します。これは、ロリポップ前のデバイスのバグです。

解決方法は、Androidのセキュリティプロバイダを使用してSSLv3を削除することです。

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."); 
    } 
} 
関連する問題