In one application I use the Android KeyStore. I have set up a password for the whole KeyStore and for each password entry. Since these passwords are strings they are stored in string members in code.
Oviously this is not safe if I want to publish the app, because a potential attacker could decompile an apk and get the password since it is hardcoded in the app.
My questions are:
Edit for clearification: I do not talk about app signing but about storing cryptographic keys in the Android KeyStore protected with passwords. The app has to have access to the password during runtime to retrieve the key entries.
Example of the current code:
String keyStorePwd = "password1";
String keyEntryPwd = "password2";
FileInputStream fis = getApplicationContext().openFileInput("sms.keystore");
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(fis, keyStorePwd.toCharArray());
SecretKey key = (SecretKey) ks.getKey("aes_key_sms_notifier", keyEntryPwd.toCharArray());
fis.close();
If your device is hacked or stolen, storing passwords on your device gives hackers easy access to all of your accounts and personal information. Although it might be tempting and convenient, you should never save passwords on your phone, tablet, or computer.
The Android Keystore provides APIs to perform cryptographic operations within this trusted environment and receive the result. It was introduced in API 18 (Android 4.3). A strongbox backed Android Keystore is currently the most secure and recommended type of keystore.
It is not recommended to store passwords in your APK. Much more when we're talking about keystore passwords. Yes, attackers can and will find ways to read passwords because that's what they do. Read recklessly included passwords in the APK. There's a way specified using gradle on how to store keystore passwords, assuming you use gradle.
PROPERTIES FILE
If you are using version control, modify your .gitignore
file to exclude keystore.properties
, which is a file that will contain your passwords. Then push it into the repo. Doing this will prevent other developers in a shared project from knowing the keystore details. You can now create the actual keystore.properties
file in the root of your project. The file should contain the following:
keyAlias yourKeyAlias
keyPassword yourKeyPassword
storeFile pathOfYourKeyStoreFile
storePassword passwordOfYourKeyStoreFile
GRADLE
After setting up your keystore.properties
file, modify your module-level gradle build file by defining a properties variable outside your android { ... }
clause such as:
def keystorePropertiesFile= rootProject.file("keystore.properties")
def keystoreProperties = new Properties()
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
android { ... }
Inside android { ... }
, declare signingConfigs { ... }
such that:
android {
signingConfigs {
config {
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']
storeFile file(keystoreProperties['storeFile'])
storePassword keystoreProperties['storePassword']
}
}
...........
}
Finally, still inside android { ... }
inside of your module-level gradle build file, you're supposed to have buildTypes { ... }
clause which contains debug { ... }
and release { ... }
configs as default. Modify the release
configurations such that:
buildTypes {
debug {
*insert debug configs here*
}
release {
*insert release configs here*
signingConfig signingConfigs.config
}
}
Defining signingConfig signingConfigs.config
in release { ... }
will allow you to automatically sign your APK whenever you choose to create a release build, all of these without storing your keystore passwords in your APK. Cheers!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With