Don’t forget to share it with your network!
Suryaprakash Narsinghbhai Sharma
Sr Developer, Softices
Mobile Development
22 September, 2025
Suryaprakash Narsinghbhai Sharma
Sr Developer, Softices
Hardcoding API keys into Java/Kotlin or XML makes them trivially discoverable with simple tools (e.g., strings, apktool, jadx). For production apps, especially those that talk to paid APIs or access sensitive data, leaking keys can mean unexpected costs, account abuse, or data exposure.
If you’re wondering how to secure API key in Android app, one effective
strategy is to leverage the Android Native Development Kit (NDK). By moving
secrets into native .so
libraries written in C/C++, you make
extraction more difficult for attackers. While this doesn’t provide perfect
protection, it does add an extra layer of security when combined with
server-side validation and runtime checks.
.so
files.
This method is widely used by developers searching for android secure API key solutions or guides on how to store API keys securely Android.
app/build.gradle
android { defaultConfig { applicationId "com.example.securekeys" minSdkVersion 24 targetSdkVersion 34 ndk { abiFilters "armeabi-v7a", "arm64-v8a", "x86_64" // specify architectures } } externalNativeBuild { cmake { path "src/main/cpp/CMakeLists.txt" } } }
Create a folder:
app/src/main/cpp/
Inside it, create native-lib.cpp:
#include <jni.h> #include <string> extern "C" JNIEXPORT jstring JNICALL Java_com_example_securekeys_NativeKeys_getApiKey (JNIEnv* env, jobject /* this */) { std::string apiKey = "your-real-api-key"; // replace with your API key return env->NewStringUTF(apiKey.c_str()); }
Security tip: Don’t use a single plaintext string in production. See Security hardening below.
Inside app/src/main/cpp/
, create CMakeLists.txt:
cmake_minimum_required(VERSION 3.10.2) project("securekeys") add_library( native-lib SHARED native-lib.cpp ) find_library( log-lib log ) target_link_libraries( native-lib ${log-lib} )
In app/src/main/java/com/example/securekeys/NativeKeys.kt:
package com.example.securekeys object NativeKeys { init { System.loadLibrary("native-lib") // must match add_library in CMake } external fun getApiKey(): String }
val apiKey = NativeKeys.getApiKey() Log.d("API_KEY", "Key: $apiKey") // debug only, don’t log in production
app/ ├── src/main/ │ ├── java/com/example/securekeys/NativeKeys.kt │ ├── cpp/ │ │ ├── CMakeLists.txt │ │ └── native-lib.cpp │ └── res/ └── build.gradle
To secure API keys in Android apps more effectively, apply these additional
techniques. They help make extracting a key from .so
files
harder:
Split the key into multiple non-obvious parts and join at runtime.
std::string part1 = "abc123"; std::string part2 = "xyz789"; std::string apiKey = part1 + part2;
This reduces detection via simple static string search.
Store an encoded/encrypted token and decode/transform at runtime:
std::string encoded = "dGVzdEtleQ=="; // base64 of "testKey" std::string decoded = base64_decode(encoded); // implement decoder
Or XOR with a runtime-generated mask (avoid hardcoding mask directly).
Build.FINGERPRINT
or package checksum validation to
detect modified APKs.
.so
files with symbol stripping (-s
link flag) and use strip
tool to remove symbol names.
Instead of shipping the real long-lived key, ship a short-lived token:
This is a highly recommended method if you’re serious about securing API keys using Android NDK together with backend protections.
To further strengthen android API key security:
.so
files can still be reverse-engineered with tools
like Ghidra or IDA.
val mapsApiKey = NativeKeys.getApiKey() mapView.getMapAsync { it.setMapStyle(MapStyleOptions.loadRawResourceStyle(this, R.raw.map_style)) Log.d("Maps", "Using key: $mapsApiKey") }
Prefer server-side key usage where possible (e.g., proxy certain requests through your backend).
If you’re searching for how to secure API key in Android app, using the NDK is a strong step toward better android API key security. By moving keys into native code, splitting and obfuscating them, and combining with runtime token exchange and backend validation, you make it much harder for attackers to steal secrets.
While no client-side solution is perfect, this layered approach: NDK + obfuscation + backend validation + monitoring is the most practical way to store API keys securely Android and maintain long-term secure API key Android practices.