2017-08-25 369 views
1

我使用Retrofit和OkHttp3來提出請求。我知道在Android 4.4 TLS 1.1和TLS 1.2不會被defult啓用。所以我試圖啓用它們。但到目前爲止,我沒有成功。我看,這可能是Android的工作室仿真器的問題,但我不能讓測試真正的設備上andoroid 4.4 rigthnow在Android 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 Services的emultaor?所以我必須要求那些沒有安裝它的用戶來安裝? –

+0

它可能是,雖然找出最好的方法是在真實設備上測試。我相信用戶應該將相應的對話重定向到GooglePlay。 –

2

當Android從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."); 
    } 
}