The output of a successful assembleRelease 🚀

Signing your APK’s, the Pragmatic Way

Roger Taracha
6 min readFeb 19, 2019

It is one thing to build an app and a totally different challenge to deploy & distribute your application to your users.

All Android package files (APK) need to be digitally signed before they are deployed to the Google Play store.

In this post, we are going to cover the process of signing your APKs and also explore & understand the inner workings of the signing process.

Debug Version:

By default, Android signs debug APKs for you, using a known key. To see this, you can use the Java keytool command.

The keystore resides in a subdirectory named .android in your home directory. The default name for the keystore is debug.keystore that has a keystore password of android.

A Java Keystore (JKS) is a repository of security certificates.

We use Java’s keytool command to create a certificate and configure its use in the signingConfigs block of your Gradle build file. (We’ll see more on signingConfigs later in this post.)

Below is a demonstration of the keytool command that lists the default debug certificate:

The keystore type is JKS, which stands for (Java KeyStore), used for public and private keys.

Java supports another type called JCEKS (Java Cryptography Extensions KeyStore), which can be used for shared keys, but isn’t used for Android applications.

The keystore has a self-signed certificate with an alias of androiddebugkey, which is used to sign debug APKs when they are deployed to connected devices or emulators.

NOTE: This might not always be the case, but in case you notice a warning at the end of the CLI output about the difference in formats (see image above), run the recommended keytool command and the output will be as demonstrated below:

💡TOP TIP 💡: To reset the debug keystore, simply delete the file debug.keystore. It will be re-created next time you deploy an app.

Release Version:

You cannot deploy a release version of an app until you sign it, which means generating a release key. This also uses the keytool utility.

Create a directory named keystoresin your systems home directory, navigate to it & run the keytool command shown below:

NOTE: The RSA algorithm is used to generate the public/private keypair of 2K size, signed with the SHA256 algorithm, valid for 10,000 days (a bit over 27 years).

Signing the APK:

Now its time to sign the APK. You could now use the jarsigner and zipalign tools to sign your APK, but it’s easier to let Gradle do it.

In thebuild.gradle file, as a child of the android closure, add a signingConfigs block, as shown below:

💡TOP TIP 💡: It is not best practice to put the passwords as hardcoded constants in the build file. A better approach would be to put them in a separate file that is not part of the Version Control System (VCS).

Remove signing information from your build files:

Instead of adding your signing information in plain text to the module’s build.gradle file, you should move this sensitive information out of the build files to prevent it from being easily accessible to others.

We start by creating a separate properties file (keystores.properties) to store secure information and refer to that file in your build files.

This file should be created in your projects’ root directory. 👇

In your module’s build.gradle file, add code to load your keystore.properties file before the android {}block.

You can refer to properties stored in keystoreProperties using the syntax keystoreProperties['propertyName'].

Modify the signingConfigs block of your module's build.gradlefile to reference the signing information stored in keystoreProperties using this syntax:

Explanation of the SigningConfig:

The DSL documentation explains that the signingConfigs block delegates to an instance of the SigningConfig class, which has four commonly used properties listed:

keyAlias: The value used in the keytool when signing a particular key.

keyPassword: A particular key’s password used during the signing process.

storeFile: The disk file containing keys and certificates, generated by the keytool.

storePassword: The password used for the keystore itself.

NOTE: There is also a storeType property (defaults to JKS) but it is rarely used.

Add the signingConfig property to the release build type

Below we demonstrate using a signing config in a release build:

Here is the complete build.gradle set up:

Generate the Release APK:

We will now invoke the assembleRelease task from Gradle that will cause the build to generate a release APK in the app/build/outputs/apk/release folder.

Navigate to your terminal on Android Studio and run this gradle command: ./gradlew assembleRelease (Mac) & gradlew assembleRelease (Windows) 👇

Success! 🙌

Takeaways:

💡TOP TIP 💡: You could choose to store your keystore.properties file in another location (for example, in the module folder rather than the root folder of the project, or on your build server if you are using a continuous integration tool). In that case, you should modify the code above to correctly initialize keystorePropertiesFile using your actual keystore.properties file's location.

NOTE: This is important — do not lose the keystore. If you do, you will not be able to publish any updates to your app, since all versions must be signed with the same key.

NOTE: Remember to add the keystore.properties file to your .gitignore file to ensure that the properties file is not added to VCS.

NOTE: You can achieve the above process using your Android Studio IDE if that is your preference 😃. Follow the link detailing this process in the Android documentation below.

Extra Reading:

S/O to Isaac Owomugisha & Nabende Simiyu for helping me edit this article. ✊

If this post was helpful, please click the clap 👏 button below a few times to show your support.

📝 Read this story later in Journal.

🗞 Wake up every Sunday morning to the week’s most noteworthy Tech stories, opinions, and news waiting in your inbox: Get the noteworthy newsletter >

--

--