When developing mobile applications, supporting older devices is a common requirement, in particular for Android mobiles where the market is much more fragmented than on iOS. According to Apple, 72% of the devices sold in the last 4 years are running iOS 12, while according to Google, only 21% of devices are running Android 8.x (Oreo). On Android, you will need to support all versions back to Android 5.x (Lollipop) to reach 90% of the active devices.
One of the challenges doing so is to continue to use state-to-the-art network protocols on operating systems released several years ago, and not always maintained anymore. For example, Android 5.x only supports TLSv1.0 and SSLv3 protocols by default, which have been proved to be insecure since then. Backend services, on the other side, now rely on TLSv1.2, in order to meet strict security requirements (NIST, PCI-DSS are just two examples).
For example, AWS AppSync endpoints only offer TLSv1.1 and TLSv1.2 during the protocol negotiation. You can verify this using the
nmap command, such as below:
So, on the client side, you have TLSv1.0 and SSLv3 by default, while on the server side, you have TLSv1.1 and TLSv1.2.
On Android Lollipop, if you try to instantiate an AppSync client using the default configuration, such as this :
You will get a runtime error like the below:
You’ll need to write an extra bit of code to use TLSv1.1 or TLSv1.2 on Android 5.x. The good news is that TLSv1.1 and TLSv1.2 are available on Android 5.x, they are just not enabled by default.
To enable these protocols, two steps are needed.
First, you will need to create your own SSLSocketFactory class. This class’ responsibility is to create and configure
SSL TLS Sockets. The implementation is mostly boilerplate code, with the exception of adding TLSv1.1 and TLSv1.2 in the list of supported protocols to new sockets.
Second, you will need to tell AppSync Client to use that new SSLSocketFactory class instead of the default. As AppSync Client is using OKHTTP library behind the scene, you’ll need first to create your own
OKHttpClient and configure it to use your
SSLSocketFactory class created just before. Then you will provide AppSync Client with your own
OkHttpClient. The code looks like this:
Full code is available on GitHub.
This is something you are likely to do only once, as one App Sync client object can be reused for all calls. I am typically instantiating it the
onCreate() method of the
Application() object, or a bit later depending if your application identifies users or not.
Now you are ready to use AppSync client with TLSv1.1 and TLSv1.2 on Android 5.x or older.
Let me know your feedback on Twitter.