Welcome to part 2 of this series of Securing Android App. You can check part 1 where we talk about how to inject MITM proxy to Android App Here: Inject MITM Proxy Android App
In this part, we will discuss the essential security protection for Android App. How can we prevent MITM Proxy injection and how to store static API Key in our app.
For our research and testing, let’s fork the library that we use in part 1. You can find it here https://github.com/esoxjem/MovieGuide
I will then forked it to here: https://github.com/bird-ac/MovieGuide
Create a Safe Vault
Create an NDK Safe Vault to store our hardcoded string. We will use it to store all of our sensitive information such as certificate SHA256, API Key, etc. We create this Safe Vault using NDK since it is effortless to read the hard coded string in java code.
First, enable NDK setting in Gradle then we create a “jni” folder inside “/src/main” then add Android.mk and Application.mk file as below
Add SafeVault.java class in com.esoxjem.movieguide.safevault package
Then let’s add the SafeVault C implementation in the jni folder.
Afterward, we can use the method in SafeVault to retrieve the hardcoded API key. But still, it will fall victim to a MITM attack. Therefore we will implement SSL pinning.
Implement SSL Pinning
One of the most important part in securing Android app from reverse engineering is definitely SSL Pinning implementation. Normally in other project this step is quite cumbersome. Luckily, this project already has proper DI set up, so it is relatively easy to add SSL Pinning. The first thing to do we need to get the SHA256 SSL certificate value from api.themoviedb.org
We can do it by going to this site: https://www.ssllabs.com/ssltest and enter the host api.themoviedb.org then click submit. After a while, it will start listing down all the servers that host the domain, and we only need to click the top one, then we will see the result.
Copy the Pin SHA256 value and put it to your safe vault. Don’t forget to add prefix “sha256/” before the sha256 value.
We need to add the SSL pinning to the dagger module that provides OkHttpClient it’s located in NetworkModule class.
The final NetworkModule class will look like this.
Implement Debug Prevention
Third step on securing Android app. With SSL pinning in place, we typically don’t need to worry about MITM, but hackers can still tamper our APK to turn on debug mode. Then they can debug our app to find out the value of our API key. To prevent it from happening, we can add DebugChecker class.
Then we add DebugChecker method to MovieListActivity, and if the user is using debug mode, force close the applications.
Implement Android App Signature Checking
With all the steps mentioned above implemented, we usually don’t need to worry much again about getting our key stolen. Still, one thing that we need to consider, tampering an Android app, is relatively easy. Therefore it might be our best case if we implement tampering protection for our app.
Generally, on our final step before uploading to google play, we will sign our APK with our Production/release key. If a hacker wants to crack open our app, they will need to break the key first. Hence, to compile back, they need to re-sign it with another key.
The first thing to do is to create a class to compare the current signer of the APK with our hardcoded keys. Let’s call it SignatureHelper
In SignatureHelper, we read the current signature and hash it to SHA1, which later we compare with our Production key’s SHA1 that we hardcode in SafeVault JNI code.
If the signing key doesn’t contain any of our hardcoded key-sets, we can assume that other parties already tamper the app, and we can force close the app.
One crucial thing to note, with this tamper protection set up in place, you might need to ensure maintaining all the debug-key, release-key, and any other signing key to the safe vault. And it might be easier for you to have all the developers in your team use the same debug key.
Android App Security
With all the steps mentioned above in place, it will be challenging for hackers to reverse-engineer your app and steal your keys. But still, it is not 100% bulletproof. And as technology is growing and your apps keep growing, it might be the best case to regularly re-assess your app’s security. Lastly, always try to prevent putting your API key hardcoded in your app.
You can check the final result in the forked repository here: https://github.com/bird-ac/MovieGuide