Implementing API key protection in a mobile application

TRUETECH is engaged in the development, support and maintenance of iOS, Android, PWA mobile applications. We have extensive experience and expertise in publishing mobile applications in popular markets like Google Play, App Store, Amazon, AppGallery and others.
Development and support of all types of mobile applications:
Information and entertainment mobile applications
News apps, games, reference guides, online catalogs, weather apps, fitness and health apps, travel apps, educational apps, social networks and messengers, quizzes, blogs and podcasts, forums, aggregators
E-commerce mobile applications
Online stores, B2B apps, marketplaces, online exchanges, cashback services, exchanges, dropshipping platforms, loyalty programs, food and goods delivery, payment systems.
Business process management mobile applications
CRM systems, ERP systems, project management, sales team tools, financial management, production management, logistics and delivery management, HR management, data monitoring systems
Electronic services mobile applications
Classified ads platforms, online schools, online cinemas, electronic service platforms, cashback platforms, video hosting, thematic portals, online booking and scheduling platforms, online trading platforms

These are just some of the types of mobile applications we work with, and each of them may have its own specific features and functionality, tailored to the specific needs and goals of the client.

Showing 1 of 1 servicesAll 1735 services
Implementing API key protection in a mobile application
Medium
~2-3 business days
FAQ
Our competencies:
Development stages
Latest works
  • image_mobile-applications_feedme_467_0.webp
    Development of a mobile application for FEEDME
    756
  • image_mobile-applications_xoomer_471_0.webp
    Development of a mobile application for XOOMER
    624
  • image_mobile-applications_rhl_428_0.webp
    Development of a mobile application for RHL
    1052
  • image_mobile-applications_zippy_411_0.webp
    Development of a mobile application for ZIPPY
    947
  • image_mobile-applications_affhome_429_0.webp
    Development of a mobile application for Affhome
    862
  • image_mobile-applications_flavors_409_0.webp
    Development of a mobile application for the FLAVORS company
    445

Implementing API key protection in mobile applications

strings app.apk | grep -i "key\|secret\|token" — first 10 lines of output already yields something interesting in most apps without protection. Google Maps API Key in AndroidManifest.xml, Firebase API Key in google-services.json, Stripe Publishable Key in code — all readable from unpacked APK without single line of reverse-engineering.

Why you can't store keys in code

Any key in string resources, class constants or app config files — public key. APK and IPA decompile. Even obfuscation only complicates search, doesn't make it impossible.

Common argument: "Firebase API Key is public, can be exposed". Technically true for apiKey in Firebase config — needed only for project identification, access controlled by Firebase Rules. But Google Maps API Key, Stripe Secret Key, keys to your own backend — different story. Maps Key leak means others' requests on your account.

Correct secret storage on device

If key must be on device (e.g. server issues token after auth) — only Keychain (iOS) or Android Keystore.

On Android:

val keyStore = KeyStore.getInstance("AndroidKeyStore")
keyStore.load(null)
// create encryption key tied to KeyStore
val keyGen = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore")
keyGen.init(
    KeyGenParameterSpec.Builder("my_key_alias",
        KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT)
        .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
        .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
        .build()
)
// encrypt token, save encrypted blob to EncryptedSharedPreferences

EncryptedSharedPreferences from androidx.security:security-crypto — convenient wrapper doing this under hood. No need to write KeyStore code manually.

On iOS Keychain Services via SecItemAdd / SecItemCopyMatching. In Swift conveniently via KeychainAccess or SwiftKeychainWrapper. Attribute kSecAttrAccessible = kSecAttrAccessibleWhenUnlockedThisDeviceOnly — data accessible only when device unlocked, don't migrate on iCloud backup.

Keys that should not be on client

API keys to external services (payment gateways, SMS providers, AI APIs) — on server. Period. Client makes request to own backend, backend makes request to Stripe/Twilio/OpenAI with its key. Client never learns this key.

Pattern for limited-use keys: client authenticates, server issues short-lived token (JWT or HMAC-signed nonce) with specific permissions. Client uses token for direct requests to service (e.g. file upload directly to S3 via presigned URL). Main key — never leaves server.

NDK and native storage

If string must be in app and can't request from server — native code. JNI function returns key assembled from parts:

JNIEXPORT jstring JNICALL
Java_com_example_NativeKeys_getApiKey(JNIEnv *env, jobject obj) {
    // key split, parts in different places
    const char part1[] = {0x41, 0x42, 0x43, 0x00};
    const char part2[] = {0x44, 0x45, 0x46, 0x00};
    // assemble + XOR decrypt
    // ...
}

This is security through obscurity, not true protection. But native code is harder to hook with automatic tools, entry threshold grows.

Build-time protection

local.properties — file outside repo, holds build variables:

MAPS_API_KEY=AIzaSy...

In build.gradle:

manifestPlaceholders = [mapsApiKey: properties["MAPS_API_KEY"] ?: ""]

In AndroidManifest:

<meta-data android:name="com.google.android.geo.API_KEY" android:value="${mapsApiKey}"/>

Key doesn't land in repo, but lands in APK — still readable from manifest. For Maps Key acceptable with proper restrictions in Google Cloud Console (restrict by Android app package name + SHA-1). For Secret Keys — no.

Timeline for implementing full scheme: audit current key position, migrate to Keystore/Keychain, move server keys to backend, configure restrictions in Google Cloud/App Store Connect — 2–3 days.