Securing Your Android Keys & Secrets with Native C++ Code

This article will guide you on how to secure your API keys, Base URLs, and other sensitive data of your app. Often times for Android apps, you want to keep secrets away from hackers or from any person who wants to reverse-engineer the app through an APK file. In this article, you will see some ways used by the Android devs to be secure and safe for your data.

There is no perfect protection mechanism to perfectly secure your data, applications, and systems from a passionate, sharp-minded hacker. So the only thing you can do in such scenarios is you can increase the security and use the best ways to be more secure. This will increase the hurdles in the ways of intruders and will take more time to sabotage the system.

Almost every app now uses some web services API. This is mostly enabled through any APU key or token. This key lets the server know that requests are coming from authenticated users and devices. Now, if you don’t keep these API keys secure, then any hacker can get access to this data through reverse engineering the APK file. This intruder can now make a flood of fake requests, which can be costly and may lead to some other serious breach issues and can create a very bad impression on your users.




Let’s talk now about some of the ways that developers use to store these API keys and other sensitive data.

Storing Keys in strings.xml File

This is a very common method to store keys. Although strings.xml is not recommended to use for the sensitive data, but often developers use this a lot. This will not keep that data secure and can be easily seen after reverse-engineering the APK file.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!--API Key-->
    <string name="api_key">abcdefg2q4qsaf34rtyy421k</string>
</resources>

Storing Keys As Constants

Another common and bad way is to make a constant of your API key and put it in a Java/Kotlin file. This is easier to use in the code to access that key, but it will cost you a lot. Only keep the things in constants which are not sensitive.

object Constants {
    const val API_KEY = "abcdefg2q4qsaf34rtyy421k"
}


Storing Keys in Gradle Files

Another way to store the API keys is putting them in Gradle files. This asks for the compiling of those keys and can be accessed only after a successful build. Developers often assume that this is a safe and secure way to hide secrets from intruders, but actually it’s not. It’s as much insecure as other methods like strings.xml or constants.

android {
  compileSdkVersion 23
  buildToolsVersion "23.0.2"

  defaultConfig {
    applicationId "com.texturelabs.rosera.pop_movies"
    minSdkVersion 14
    targetSdkVersion 23
    versionCode 1
    versionName "1.0"

    // THE API KEY FOR YOUR APP
    buildConfigField("String", "API_KEY", "abcdefg2q4qsaf34rtyy421k")
  }
  buildTypes {
    release {
      minifyEnabled false
      proguardFiles getDefaultProguardFile('proguard-android.txt'),↵
       'proguard-rules.pro'
    }
  }
}

This can be accessed in your code through BuildConfig.API_KEY.


Storing Keys Natively with C++

In Android Apps, you write code in Java or Kotlin, and it is easy to decompile the code written in Java and Kotlin as compared to C/C++ native code. Thus, there is a way to hide your Keys using C/C++ which is secure and safer than the previous ways.

Let’s look at the way to hide the API key by a code example. First, you have to install NDK (Native Development Kit) which allows C/C++ code to work with Android Studio and CMake to build your C/C++ code.

Now, make a folder name cpp in App’s src > main > and create a C++ file in it with the name native-lib.cpp. Put this code snippet in that cpp file.

#include <jni.h>
#include <string>

extern "C" JNIEXPORT jstringJNICALL

Java_com_package_name_YourKeys_apiKey(JNIEnv *env, jobject object) {

   std::string api_key = "your_api_key";

   return env->NewStringUTF(api_key.c_str());
}

Here com_package_name is the actual package name of your app. Note that instead of the dots, here are the underscores. So, com.package.name becomes com_package_name.

Then _YourKeys is the name of .kt file which allows you to access the API key in Java/Kotlin files from C++ code.

Next to it, _apiKey is the name of the function which will return you the actual API key to make it accessible throughout your App.

This is enough for C++ code, now you have to create that YourKeys.kt file, and write the following code;

object YourKeys {

    init {
        System.loadLibrary("native-lib")
    }

    external fun apiKey(): String
}

The code is used to access the keys throughout the application. Note that the apiKey method doesn’t have any method definition. The external modifier makes sure that this method’s definition is brought from the native C++ code through the native-lib.cpp file.

You can add more keys and sensitive data by creating more methods in both YourKeys.kt and native-lib.cpp files following the convention explained about of placing package_name_File_Name_method_name etc.

In the end, wherever you want to access the API key either while making some retrofit instance or whatever you need forl, you just have to write YourKeys.apiKey().

And that’s it. Now you can remain confident that your API keys and secrets are safe and sound and can not be easily viewed through reverse engineering the APK file.

At the end, please Subscribe to my newsletter #Time with Wajahat to learn learn about the life experiences, lessons, career advices, technology & programming tips manually handcrafted and curated by Wajahat Karim.


If you liked this article, you can read my new articles below:


profile card
Wajahat Karim
🌍 Making the world a better place, one app at a time.
🔥 Google Developer Expert (GDE) in Android . 📱 Professional Android Developer with ~10 years experience. 💻 Creator of various Open Source libraries on Android . 📝 Author of two technical books and 100+ articles on Android. 🎤 A passionate Public Speaker giving talks all over the world.
Author's picture

Wajahat Karim

🔥 Google Dev Expert (GDE) in Android .
📱 Android Dev. 💻 Open Source Contributor . 📝 Technical Writer . 🎤 Public Speaker

Senior Android Developer

Karachi, Pakistan