【问题标题】:Enable TLS 1.2 in Android 4.4在 Android 4.4 中启用 TLS 1.2
【发布时间】:2018-02-03 06:02:25
【问题描述】:

我使用 Retrofit 和 OkHttp3 来发出请求。我知道在 Android 4.4 中,TLS 1.1 和 TLS 1.2 没有被默认启用。所以我正在尝试启用它们。但到目前为止,我还没有成功。我读到这可能是 android studio 模拟器的问题,但我无法在带有 andoroid 4.4 rigthnow 的真实设备上进行测试

这是我到目前为止所做的:

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 类

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)

【问题讨论】:

  • 感谢这段代码为我解决了这个问题

标签: android retrofit2 android-4.4-kitkat tls1.2 okhttp3


【解决方案1】:

请试试这个: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。

【讨论】:

  • 我收到了 GooglePlayServicesNotAvailableException。这意味着我无法更新提供程序。可能是因为我使用的模拟器没有安装 Google Play 服务?所以我得请没有安装它的用户安装,对吗?
  • 可能是这样,但最好的方法是在真实设备上进行测试。我相信用户应该得到适当的对话框,将他们重定向到 GooglePlay。
【解决方案2】:

当 android 从 TLSv1 回退到 SSLv3 时,通常会发生该错误。这是棒棒糖之前的设备中的一个错误。

解决方案是使用 Android 的 security Provider 移除 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.");
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-25
    • 2020-05-03
    • 1970-01-01
    • 1970-01-01
    • 2019-06-04
    • 2019-04-12
    • 2016-01-25
    • 2018-10-31
    相关资源
    最近更新 更多