Включить TLS 1.2 в Android 4.4
Я использую 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 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;
}
}
Я попробовал это, но не сработало.
Моя ошибка: 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.
Эта ошибка обычно возникает, когда Android возвращается к SSLv3 из TLSv1. Это ошибка в устройствах перед леденцом на палочке.
Решение состоит в том, чтобы удалить SSLv3 с помощью провайдера безопасности Android.
попробуйте это решение:
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.");
}
}