Probably related to: https://github.com/square/okhttp/issues/4042
Works as charm on Android 5 and up, but...
Device:
2 devices with Android:
Sony E2003 4.4.4
Samsung GT-I9506 4.4.2
Setup:
okHttpVersion = '3.10.0'
retrofitVersion = '2.4.0'
implementation "com.squareup.okhttp3:okhttp:$okHttpVersion"
implementation "com.squareup.okhttp3:logging-interceptor:$okHttpVersion"
implementation "com.squareup.retrofit2:retrofit:$retrofitVersion"
implementation "com.squareup.retrofit2:converter-gson:$retrofitVersion"
implementation "com.squareup.retrofit2:converter-scalars:$retrofitVersion"
implementation "com.squareup.retrofit2:adapter-rxjava2:$retrofitVersion"
This is working for
okHttpVersion = '3.9.1'
retrofitVersion = '2.3.0'
but it looks like the reason is okhttpVersion='3.10.0' (also in retrofit 2.4.0 dependencies)
Stacktrace part:
Cannot establish TLS with new.services.tv.nu:443 (sni: {OUR_SERVER_ADDRESS}: TlsException("SSL handshake error: Error([('SSL routines', 'SSL23_GET_SERVER_HELLO', 'sslv3 alert handshake failure')],)",)
Caused by: javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x7b7ce0c8: Failure in SSL library, usually a protocol error
I expect failure lies within Cipher Suites scope:
version = 3.10.0
Client supported
TLS_RSA_WITH_AES_256_CBC_SHA
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
TLS_RSA_WITH_3DES_EDE_CBC_SHA
TLS_EMPTY_RENEGOTIATION_INFO_SCSV
Server Chosen
version = 3.9.1
TLS_RSA_WITH_AES_256_CBC_SHA
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA - Server Chosen
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
TLS_RSA_WITH_3DES_EDE_CBC_SHA
TLS_EMPTY_RENEGOTIATION_INFO_SCSV
Server Chosen
Can confirm, that this issue exists in 10 version. And none of available workarounds didn't help.
Would the GMS provider help you here? The reason for reducing old ciphers and protocols is that they are not secure and shouldn't be used.
https://developer.android.com/training/articles/security-gms-provider
We have the same issue on Android 4. Is there any known workaround?
@florianreinhart only downgrading into 9 version helps me. You can try using GMS provider. It will work on 4.4. But user need have installed Google Play Services and this "hack" may not work on systems that <4.4.
You can manually enable the legacy ciphers suites by creating a custom ConnectionSpec.
// Add legacy cipher suite for Android 4
List<CipherSuite> cipherSuites = ConnectionSpec.MODERN_TLS.cipherSuites();
if (!cipherSuites.contains(CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA)) {
cipherSuites = new ArrayList(cipherSuites);
cipherSuites.add(CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA);
}
final ConnectionSpec spec = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
.cipherSuites(cipherSuites.toArray(new CipherSuite[0]))
.build();
OkHttpClient client = new OkHttpClient.Builder()
.connectionSpecs(Collections.singletonList(spec))
.build();
If it's easy for anyone here, could you test with a snapshot build? https://oss.jfrog.org/artifactory/libs-snapshot/com/squareup/okhttp3/okhttp/3.11.0-SNAPSHOT/
It theoretically supports TLS1.2 on Android back to 4.1. I'd love confirmation that is really the case.
In order to support OkHttp 3.10 + Android 4.x your server needs to support one of these cipher suites:
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
TLS_RSA_WITH_AES_128_CBC_SHA
TLS_RSA_WITH_AES_256_CBC_SHA
SSL_RSA_WITH_3DES_EDE_CBC_SHA
More details on the spreadsheet! http://tinyurl.com/okhttp-cipher-suites
No further action for us to take on this.
Best fix: change your server鈥檚 TLS configuration to support one of the 5 good Android 4.x cipher suites (above).
Workaround: customize cipher suites to restore legacy behavior:
// Necessary because our servers don't have the right cipher suites.
// https://github.com/square/okhttp/issues/4053
List<CipherSuite> cipherSuites = new ArrayList<>();
cipherSuites.addAll(ConnectionSpec.MODERN_TLS.cipherSuites());
cipherSuites.add(CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA);
cipherSuites.add(CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA);
ConnectionSpec legacyTls = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
.cipherSuites(cipherSuites.toArray(new CipherSuite[0]))
.build();
OkHttpClient client = new OkHttpClient.Builder()
.connectionSpecs(Arrays.asList(legacyTls, ConnectionSpec.CLEARTEXT))
.build();
@swankjesse So OkHttp versioning does not follow semver? I鈥檇 consider this a breaking change.
@florianreinhart specifically with HTTPS, OkHttp tries to stay current with the dynamic TLS ecosystem it interacts with. We retire obsolete cipher suites tracking major browsers. Details on our reasoning are here: https://github.com/square/okhttp/wiki/HTTPS
@Swirastlynn looks like cloudflare cdn not supporting any of this ciphers.
@stalkerg have you tested with 3.11? I'm curious whether the additional TLS 1.2 support helps here.
@yschimke I still need to use hack with custom SSLSocketFactory
Your fix does not work for Android older than 5.0
@PromanSEW Any working solution for Android < 5? i had to downgrade to 3.8.0
Most helpful comment
No further action for us to take on this.
Best fix: change your server鈥檚 TLS configuration to support one of the 5 good Android 4.x cipher suites (above).
Workaround: customize cipher suites to restore legacy behavior: