Понимание: >
Похоже, что в Android 4.x TLS 1.2 или 1.3 не включен по умолчанию.
Попытки решения:
сильный>
Я пробовал следующие подходы:
- Реализация SocketFactory
- Принудительное исполнение определенные протоколы с использованием ConnectionSpec
- Использование ProviderInstaller.installIfNeeded(this) (но оно недоступно из-за отсутствия сервисов Google Play на устройствах, управляемых компанией)
Фрагмент кода:
Код: Выделить всё
ConnectionSpec spec = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
.tlsVersions(TlsVersion.TLS_1_1, TlsVersion.TLS_1_2)
.cipherSuites(
CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA,
CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA
)
.build();
OkHttpClient.Builder okHttpClientBuilder = new OkHttpClient.Builder();
okHttpClientBuilder.connectTimeout(10, TimeUnit.SECONDS);
okHttpClientBuilder.readTimeout(10, TimeUnit.SECONDS);
okHttpClientBuilder.connectionSpecs(Arrays.asList(spec));
okHttpClientBuilder.addInterceptor(new Interceptor() {
@NonNull
@Override
public Response intercept(@NonNull Chain chain) {
Request request = chain.request().newBuilder()
.addHeader("Accept", "application/json")
.addHeader("Authorization", "Basic ....")
.build();
try {
return chain.proceed(request);
} catch (NoSuchElementException | IOException e) {
e.printStackTrace();
return new Response.Builder()
.protocol(Protocol.HTTP_1_1)
.code(500).build();
}
}
});
try {
okHttpClientBuilder.sslSocketFactory(new TlsSniSocketFactory(), getTrustManager());
} catch (KeyManagementException e) {
throw new RuntimeException(e);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
} catch (KeyStoreException e) {
throw new RuntimeException(e);
}
OkHttpClient okHttpClient = okHttpClientBuilder.build();
retrofit = new Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl("....")
.client(okHttpClient)
.build();
TestTLSService testTLSService = retrofit.create(TestTLSService.class);
updateAppRemoteCall = testTLSService.fetchAPKForUpdate();
try {
ProviderInstaller.installIfNeeded(this);
} catch (GooglePlayServicesRepairableException e) {
GooglePlayServicesUtil.getErrorDialog(e.getConnectionStatusCode(), this, 0);
} catch (GooglePlayServicesNotAvailableException e) {
Log.e("SecurityException", "Google Play Services not available.");
}
try {
updateAppRemoteCall.enqueue(new Callback() {
@Override
public void onResponse(Call call, retrofit2.Response response) {
Log.d("DEBBUG", ""+response.code());
Log.d("DEBBUG", ""+call.request().url());
Log.d("DEBBUG", ""+response.body().toString());
}
@Override
public void onFailure(Call call, Throwable t) {
t.printStackTrace();
}
});
}catch (Exception e){
e.printStackTrace();
}
Несмотря на все эти усилия, я продолжаю получать следующую ошибку:
Код: Выделить всё
error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure (external/openssl/ssl/s23_clnt.c:744 0x67c32ec8:0x00000000)at .startHandshake(OpenSSLSocketImpl.java:449)
... (stack trace)
Caused by: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x6c9573e0: Failure in SSL library, usually a protocol error
... (stack trace)
Устройства, о которых идет речь, находятся под управлением компании и на них отсутствуют сервисы Google Play.
Вопросы:
- Существуют ли альтернативные подходы к включению поддержки TLS 1.2 на устройствах Android 4.x без сервисов Google Play?
- Есть ли способ изящно справиться с этим ошибку и предоставить пользователю более информативное сообщение?
Подробнее здесь: https://stackoverflow.com/questions/792 ... e-play-ser
Мобильная версия