Hide Secured Infomation in Android App

Homan Huang
3 min readMay 2, 2021

It’s important to hide your secured information in your Android apps, such as an API key or token. The local.properties is a great file to store this kind of information. It’s not a problem to store in a different file but you need to manually insert the file name into configuration.

— === M e n U === —

🍓 1. Why use local.properties?
🐾 2.
Add a Property in Build.Gradle
🐩 3.
Use the New Property
🐝 4.
Other Choice: gradle.property

🍓 1. Why use local.properties? …… → Menu

Let’s open the Project View of your app, and open the .gitignore file.

*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
.externalNativeBuild
.cxx
local.properties

Have you found the file? The local.properties file is ignored by default before you commit the change on the project. You’ll save an extra step to input a file in .gitignore.

🐾 2. Add a Property in Build.Gradle …… → Menu

We need to define a variable in Build.Gradle of the module.

Grab info from local.properties

plugins {...}

// get property from local.properties
def getProps(String propName) {
def propsFile = rootProject.file('local.properties')
if (propsFile.exists()) {
def props = new Properties()
props.load(new FileInputStream(propsFile))
return props[propName]
} else {
return "";
}
}

android {...}

Add API Info in local.properties

sdk.dir=...

APP_TOKEN
="1234567890"

Add Variable in BuildConfig

android {
...

defaultConfig {
...

// BuildConfig: Type Var Value
buildConfigField("String", "APP_TOKEN", getProps('APP_TOKEN'))

Easy job!

🐩 3. Use the New Property …… → Menu

Hilt Module example in Kotlin:

import YOUR.PACKAGE.BuildConfig.APP_TOKEN
...

@Module
@InstallIn(SingletonComponent::class)
object ApiInterceptorModule {
@Provides
@Singleton
fun provideInterceptor(): Interceptor = Interceptor { chain ->
val requestBuilder = chain.request().newBuilder()
requestBuilder.header("Content-Type", "application/json")
requestBuilder.header("X-App-Token", APP_TOKEN)
chain.proceed(requestBuilder.build())
}
}

Usage: BuildConfig.Variable Name
😍: I can add as many constants as I like to in buildConfigField.

🐝 4. Other Choice: gradle.property …… → Menu

Let’s try to insert the secured information in a different file, such as gradle.property.

gradle.property

...
APP_TOKEN
="1234567890"

build.gradle

Different with local.properties, you can save a step to import the value. Any settings in the gradle.property will directly import to gradle.

// APP_TOKEN from gradle.properties hidden in .gitignore
// BuildConfig: Type Var Value
buildConfigField("String", "APP_TOKEN", APP_TOKEN )

.gitignore

However, you need to add gradle.property in .gitignore.

*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
.externalNativeBuild
.cxx
local.properties
gradle.properties

🤐 5. New Plugin — Secrets

The above method is the manual readable style. There is a new plugin which can save our works.

gradle.module — plugins

plugins {
...
id 'com.google.secrets_gradle_plugin' version '0.6'
}

gradle.module — secrets

secrets {}

You can set two type of files: default or specific file.

secrets —defaultProperties:

defaultPropertiesFileName 'local.defaults.properties'

secrets — properties:

propertiesFileName 'local.properties'

secrets — ignoreList:

In local.properties, there are some value we don’t need in the code, such as

sdk.dir=C\:\\Users\\Homan\\AppData\\Local\\Android\\Sdk

So, we can ignore that value.

ignoreList.add("sdk.*")

How to use them

In Kotlin:

Log.d(TAG, "Call local properties: ${BuildConfig.mapKey}")

In AndroidManifest.xml:

android:value="${mapKey}"

Clap..clap…

😉: If you like my article, thanks!…… → Menu

--

--

Homan Huang

Computer Science BS from SFSU. I studied and worked on Android system since 2017. If you are interesting in my past works, please go to my LinkedIn.