21

I'm using OkHttp 3.12.2 on Android 9 (Pixel 2 device) and try to connect to an nginx 1.14.0 running with OpenSSL 1.1.1. The nginx is capable of TLSv1.3, I verified this with Firefox 66.0.2 on Ubuntu 18.04, Chrome 73.0 on Android 9 and ChromeOS 72.0.

However, OkHttp always negotiates TLSv1.2. I also tried to set a RESTRICTED_TLS ConnectionSpec, but it didn't help.

I did not find a specific instruction on how to get TLSv1.3 working on Android. I know that only Android 8 and 9 support TLSv1.3 out of the box; I'm fine for now with that restriction.

My experience from earlier TLS migrations is that I don't have to do anything except updating all involved components.

Andreas
  • 529
  • 1
  • 6
  • 9

2 Answers2

29

As shown in official link, TLSv1.3 is supported from Android 10(Api Level 29) on wards. So to support TLSv1.3 in previous versions we can integrate the conscrypt library. Conscrypt security provider includes a public API for TLS functionality. For that we have to add the dependency,

dependencies {
  implementation 'org.conscrypt:conscrypt-android:2.2.1'
}

Here also we need OkHttp client as it supports conscrypt.

As documented in OkHttp,

OkHttp uses your platform’s built-in TLS implementation. On Java platforms OkHttp also supports Conscrypt, which integrates BoringSSL with Java. OkHttp will use Conscrypt if it is the first security provider.

After adding conscrypt dependency, in application class we just have to mention,

Security.insertProviderAt(Conscrypt.newProvider(), 1);

This can be helpful to provide support and enable TLS 1.3 in older android version (Api level <29).

Dhaval Shah
  • 618
  • 6
  • 15
  • Correct me if I was wrong, code from OkHttp `Platform.kt` suggests otherwise. It will first match android and then Conscrypt. `ConscryptPlatform` instance will not be returned from method `Platform.Companion.findPlatform` on android devices. – hqzxzwb Mar 09 '20 at 07:48
8

The problem is likely, that the client or the certificate might not support TLS 1.3 in all situations - and then will fall back. Try running SSL test to verify that (it also performs checks for mobile clients, which might negotiate differently). Upgrading OhHttp to 3.13 or 3.14 (soon) might also be an option; here's the change log. even if Android should support it, the client needs to be configured, as well:

OkHttpClient client = new OkHttpClient.Builder()
    .connectionSpecs(Arrays.asList(ConnectionSpec.MODERN_TLS))
    .build();

Possible values there are: RESTRICTED_TLS, MODERN_TLS and (backwards) COMPATIBLE_TLS.

Martin Zeitler
  • 1
  • 19
  • 155
  • 216
  • I should have mentioned that I already ran the SSL test and [it passes](https://www.ssllabs.com/ssltest/analyze.html?d=schildbach.de&latest) the TLSv1.3 tests. All TLSv1.3 cipher suites are supported: TLS_AES_256_GCM_SHA384, TLS_CHACHA20_POLY1305_SHA256 and TLS_AES_128_GCM_SHA256. – Andreas Apr 06 '19 at 19:28
  • @AndreasSchildbach (updating and/or) explicitly setting `MODERN_TLS` or `RESTRICTED_TLS` still might result in a different protocol negotiation. no clue what the default value is. – Martin Zeitler Apr 06 '19 at 19:30
  • I'm afraid I can't update to OkHttp 3.13 and beyond because Square hiked the requirements too far for me (using Java 8 language features require a recent Android Gradle plugin which breaks deterministic builds due to a long-standing bug). But OkHttp 3.12.x is receiving backports they say. – Andreas Apr 06 '19 at 19:30
  • As I mentioned in the description, I set the client to RESTRICTED_TLS. Default is MODERN_TLS afaik, which also doesn't work. – Andreas Apr 06 '19 at 19:31
  • @AndreasSchildbach there was a bug filed against `javax.net.ssl`: https://bugs.openjdk.java.net/browse/JDK-8202625 & https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8202625 make sure the version you are using is not affected by that. testing with a [TLS 1.3 only client](https://blog.gypsyengineer.com/en/security/an-example-of-tls-13-client-and-server-on-java.html) might also help to rectify the culprit. – Martin Zeitler Apr 06 '19 at 19:38
  • 1
    I suddenly have the feeling Android 9 doesn't support TLSv1.3 yet, despite me remembering reading about it 2 years ago. I just tried running `SSLContext.getInstance("TLSv1.3");` but got `java.security.NoSuchAlgorithmException: TLSv1.3 SSLContext not available`. And the changelog for Android Q (unreleased) does [mention it](https://developer.android.com/preview/features#tls-1.3) like a new feature. – Andreas Apr 06 '19 at 20:03
  • 1
    Yep, you need Q. https://twitter.com/jessewilson/status/1106035125878513664 – Jesse Wilson Apr 07 '19 at 20:46