4 Strategies to Secure API keys in Android Applications (Cheat Sheet Series)
π§π»βπ« This article is part of our βAndroid Cheat Sheet Seriesβ in which we provide a condensed overview of the most practical solutions to a common problem or question in the Android framework, and further, provide links to detailed guides for implementing these solutions.
Why should I secure my API-Keys?
Api-Keys are considered secret values that only the developer should know of. They are keys to accessing our servers and have to be kept safe. Hackers might try to acquire your API-Keys to launch a DDoS attack on your servers or abuse it to access 3rd party services and cost you money. In this article we have provided 4 of the most recommended ways to secure an API-Key in an Android project, starting with the most straightforward method and moving on to more complicated ones.
1. Secure API keys from public repositories.
When pushing your code to a public repository (or in our opinion, even a private repository inside a company), you should not include your Api-Keys as plain strings inside your Java/Kotlin classes or resource files. The best practice to exclude Api-Keys from being pushed to repository while being able to use them inside your project is to include them inside a custom_name.properties
file.
π Link to the best implementation guide for this solution: Click!
π Pros: Your API key is not accessible to anyone that has access to the repository (For example on GitHub, GitLab, etc.)
π‘ Cons: Your API-Key will still be inside your .apk
file and vulnerable to decompilation.
2. Obfuscate your code.
As mentioned previously, although moving the API-Key to custom_name.properties
is a good practice but still attackers can decompile your APK file and extract the api-keys from it. To address this issue it is recommended to use ProGuard or R8 for code obfuscation. This practice enhances the complexity for potential attackers attempting to reverse-engineer your application and retrieve sensitive API keys.
π Link to the best implementation guide for this solution: Click!
π Pros: It makes it harder for the attacker to find your API-Key inside the decompiled APK source as all classes, methods, and fields will be renamed.
π‘ Cons: While Proguard makes the process of locating the API-KEY difficult as it renames classes and fields in your source code, the API-KEY itself will remain in the form of a plain string and can eventually be found by an attacker. However, there are solutions to that as well which I will explain below.
π€ Found this article useful so far? Then please hold down the π button for a few seconds! Your support fuels my passion for sharing knowledge, and it encourages me to keep delivering valuable content. Now, letβs dive back into the Cheet Sheet and explore more insights together!
3. Use NDK to store API-KEY inside a β.cppβ file.
Some recommend storing your API-Key inside a .cpp file (C++ language) and accessing it using NDK from inside your Kotlin/Java code. Although our research shows that the stored API-Key inside the .cpp file is still accessible via decompiling .cpp files, it seems that this method makes it a bit harder for the attacker to access your API-Keys, especially if used in conjunction with previous (obfuscation) and next (encryption) method.
π Link to the best implementation guide for this solution: Link1!, Link2!
π Pros: It makes it harder for the attacker to decompile your whole project because now they also have to take extra steps to decompile your C++/Native files.
π‘ Cons: If an attacker goes to the trouble of decompiling the C++/Native files, they can still access their content unless itβs obfuscated and encrypted.
4. Encrypt API keys to prevent reverse engineering.
While previous steps help a lot with securing your API-keys, the true security (hopefully π ) comes from this step. In order to make sure that the attacker can not access your plain-string API-Key even after decompiling your APK, you can encrypt your API key with your algorithm of choice and store the encrypted string inside your project, then decrypt it whenever you need it. Base64 is one of the frequent encryption algorithms. It is worth noting that the DexGuard (a paid and more advanced version of ProGurad) can encrypt values such as strings inside your project. Use them in conjunction with obfuscation to benefit maximum security.
π Link to the best implementation guide for this solution: Click!
π Pros: Even after decompiling your APK (static reverse engineering) or performing a basic MITM attack, the attacker has the encrypted version of your API-Key which is useless without knowing its encryption algorithm.
π‘ Cons: There is a possibility that the attacker might somehow find out your encryption algorithm if you use a frequently used encryption algorithm. Also there is possibility of dynamic reverse engineering or dynamic analysis (such as bypassing certificate pinning and hooking network functions).
Is my API-Key finally secure?!
We discussed 4 different ways to safeguard API-Keys inside your Android application. it is a good practice to use a mixture of the aforementioned solutions. In our opinion, obfuscation + encryption is a must, while accessing the API-Key through NDK adds another layer to this security structure. But bare in mind, no matter how hard you try, at the end of the day, your API-Key is residing inside your APK which is out in the public. There are interesting techniques available that completely omit a need for an API-Key inside your Android project which you can read more about here.
π₯³ Enjoyed this article? Hold down that π button for a few seconds to show your support! Donβt forget to hit the Follow button to stay updated on future Cheet Sheets. Happy coding!
β οΈ List of other Cheat Sheet Series articles: Click!
β οΈ Disclamair: The solutions mentioned in this article are based on the best practices recommended by experienced developers in the Android community. We do not guarantee their functionality and reliability. This article is for educational purposes only. use at your own discretion.