Skip to main content

Sign your Android release APK - Secure way


Why read?

  • If you are a Android developer (or wannable one🙌) and want to publish your own app on GooglePlay, you will need to sign your APK digitally with a certificate.  
  • If you are rather an experienced android developer, you might be interested in learning best and secure way to configure build.gradle for signing multiple flavors seamlessly.
  • Besides above two, this article is for anyone who is curious about Android Apps
  • For more detailed information on why you need to sign your APK read here.
While writing this post, I am assuming that you know the basics about android apps and android development tools: Android Studio, Android SDK, JDK etc. If you are not familiar with these, please android checkout android developer training page

Generating Private Key and Key store

If you don’t already have a Keystore file with you, following steps explain how you can create one using Android Studio:
  • Click Build-> Create Signed APK-> to open the Generate Signed APK dialog. Click Create New button
  • Provide following details in New Key store dialog as below:
Key store Path: path and name of key store file
          Password: Password for key store file
          Key
create new keystore and key
Alias: Enter an identification for your private key
Password: Password for your private key. This should be different from Keystore password.
Validity (years): Minimum 25 years. This is the expiry time of your key post which you can no longer provide updates for your apps signed with this key.
Certificate: provide some information about yourself and your organization. This information with not be displayed anywhere in the app but will be included in the certificate as a part of the APK.
  • Click OK. New key store file will be generated and saved a given path
Note: Screenshots and examples are created using Android Studio 3.0 and Android O SDK.  To know more about what is new in Android studio 3.0 , read here. Checkout the latest features available in Android O SDK (API level 26) read here.

Configure auto signing with Gradle – secure way

Generally, if you use Android studio Signing Wizard to configure signing for your release app, it will add configs as plain test in your app/buil.gradle, which is not secure. It looks something like this:

android {
    signingConfigs {
        release {
            keyAlias
'myappkey'
           
keyPassword 'abc123'
           
storePassword 'xyz123'
           
storeFile file(/home/Projects/keystore_files/MyAppKey.jks')
        }
    }
In a distributed development environment, where multiple stakeholders/developers working in different modules of your application, this info should be accessible to everyone. 

Remove sensitive signing information from build.gradle

Keeping all sensitive info such as passwords, keystore file, key name/alias in your app/build/.gradle is not safe because if this info  reaches into wrong hands than your application security is compromised. Anyone having your keystore file access and metadata can easily play your app and thus as a developer your credentials are at stake. To prevent such attacks to your application, you should not reveal these sensitive values into your source code and instead use only references to the actual values stored at a location outside your source code.
To configure your build.gradle to read all these sensitive details from a .properties file stored at any secure location in disk, follow the steps below: 

1. Create a new file keystore.properties at any location:

Choose any location (say D://Projects/Android/Signing/) outside your project. Add the actual values into this file as below:
storePassword=abc@123
keyPassword=xyz@123
keyAlias=myappkey
storeFile=D://Projects/Android/keystore_files/MyAppKey.jks

2. Open you app/build.gradle file and add below lines on top:

apply plugin: 'com.android.application'
def keystorePropertiesFile = file("D://Projects/Android/Signing/signing.properties")
// Initialize a new Properties() object called keystoreProperties.
def keystoreProperties = new Properties()
// Load your keystore.properties file into the keystoreProperties object.
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
android {
….
          } 

3. Now refer to keystore actual values inside signingConfigs using keystoreProperties['propertyName

…
android {
    signingConfigs {
        release {
            keyAlias keystoreProperties['keyAlias']
            keyPassword keystoreProperties['keyPassword']
            storeFile file(keystoreProperties['storeFile'])
            storePassword keystoreProperties['storePassword']
        }
    }
          buildTypes {
                 release {
                 signingConfig signingConfigs.release
                 ..
          }
        …

 4. Configure different key store for each flavour

You can also configure your build.gradle to sign different flavours with a different key store. For that, you can simply create as many configs inside signingConfigs{}, and then assign them to  corresponding flavours.

…
android {
    signingConfigs {
        free{
            keyAlias keystoreProperties['keyAliasPaid']
            keyPassword keystoreProperties['keyPasswordPaid']
            storeFile file(keystoreProperties['storeFilePaid'])
            storePassword keystoreProperties['storePasswordPaid']
        }

 paid{
     keyAlias keystoreProperties['keyAliasFree']
     keyPassword keystoreProperties['keyPasswordFree']
     storeFile file(keystoreProperties['storeFileFree'])
     storePassword keystoreProperties['storePasswordFree']
}
...
}

buildTypes{
        freerelease {
           signingConfig signingConfigs.free           minifyEnabled true           shrinkResources true          //proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'           proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'          }
         paidrelease {
           signingConfig signingConfigs.paid           minifyEnabled true           shrinkResources true
           proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
} }
  ...
Done! To verify everything works well, just select any of the 'release' variant from Build Variants tab. 
build variants 

Keep It safe!

Finally, don’t forget to save your Key store file and related info at secure place.


Comments

Popular posts from this blog

What is new in Android O (API level 26) Developer SDK

With each new version of Android, a corresponding version of Android SDK is also realised for App developers. New version of Android comes up with some new features, new hardware /software support and some new APIs are also written by Google developers. Therefore, new SDK release is named after the API level of the Android Framework it is written for. Version Code name Launch Devices 8.0 Oreo Pixel 7.1 Nougat Pixel , Pixel XL 7.0 Nexus 5X , Nexus 6P 6.0 Marshmallow 5.1 Lollipop Android One 5.0 Nexus 6 , Nexus 9 4.4 KitKat Nexus 5 4.3 Jelly Bean Nexus 7 2013 4.2 Nexus 4 , Nexus 10 4.1 Nexus 7 4.0 Ice Cream Sandwich Galaxy Nexus 2.3 Gingerbread Nexus S Each new version of Android SDK essentially aimed to achieve some or all of the following: ...