Posted on by

I must admit that when I started developing mobile apps, I was confused by the various requirements for protecting apps and guaranteeing their authenticity. On the iOS side, you have terms like entitlement, provisioning profile, bundle ID, and a host of other things. Android has similar functionality and their phrasing is equally confusing, including terms such as keystore, key hash, alias and, in addition, there are commands which must be entered on the command line.

This week’s tutorial looks specifically at the Android signing process with the goal of bringing clarity and understanding to this potentially complex topic.

The Keystore

The basics behind protecting your Android app is to use a generated certificate and digital “key” which provides a unique, encrypted, and reasonably un-hackable signature. This proves that the app came from you, not some other suspicious source.

On Android, this is done via a keystore. The keystore is a simple file with a really large block of encrypted data. This file can be stored anywhere on your computer, and this is generally the first problem that developers encounter. Because there’s no standard location in which to store these, it’s easy to “lose” them — we will address this issue in a bit.

Next, there are two types of keystores that you should be aware of: debug and release. The debug keystore should be used while developing your app — for example, it can be used when manually installing (side-loading) apps to local Android devices. However, the debug keystore can not be used for an app destined for Google Play or Amazon — for this, you must use a release keystore.

For both types, a keystore is identified by two aspects: the filename that it’s stored in and an alias. Because a keystore file could potentially store multiple keystores, each one is identified by an alias. In most cases, you’ll only have one certificate/key pair in a file, but you still need to give it an alias.

Keystore files are also protected by a pair of passwords: one for the keystore file itself and another for each keystore/alias pair within the file. While these passwords should ideally be unique, most developers use the same password for both.

Debug

Debug keystores are somewhat standard. Google provides one with the Android Developer Tools but, for your convenience, Corona provides you with a debug keystore as well. This keystore is located in a standardized folder within your CoronaSDK application folder and you should use it while developing Corona apps.

CoronaSDK/Resource Library/Android/debug.keystore

Release

To create a release keystore for your app, you need to execute a command from your OS command line. For OS X, this is done via the Terminal app in which you’re presented with a $ prompt. For Windows, this is done via the Command Prompt which can be accessed by opening the Start menu and searching for cmd. In Windows, you’ll be presented with a prompt like: C:\>

As mentioned above, there’s no standard place to store keystore files, so it may be useful to create a folder specifically for this. By default, both the OS X Terminal and Windows Command Prompt will start within your “home” directory. On Mac, this translates to /Users/yourloginname and on Windows it translates to something like C:\Users\yourloginname. Within this home folder, you can create a folder to hold your keystores.

In Windows, type:

md Keystores

In OS X, type:

mkdir Keystores

Once this is done, you can access the folder by typing:

cd Keystores

Once inside the Keystores directory, you should issue a command that’s fairly complex. Before proceeding, it’s very important to understand that this is not a “copy-and-paste” procedure — you must substitute values that are specific to the keystore you wish to generate.

For the moment, let’s carefully inspect and dissect the following line:

keytool -genkey -v -keystore mykeystore.keystore -alias aliasname -keyalg RSA -validity 999999

Essentially, the first term means that this line will execute a program called keytool. For OS X, this should be installed already, but Windows users may need to install it (see below). Following this, all of the parts that begin with a hyphen (-) indicate parameters for the keytool command. Those options are as follows, and those in bold are the two which must be customized (the others can remain as shown):

  • -genkey — Tells keytool to generate a key.
  • -v — Tells keytool to be verbose (i.e. tell you what it’s doing).
  • -keystoreThe filename to save the keystore as.
  • -aliasThe alias name to identify the keystore.
  • -keyalg RSA — This says to use the RSA method to generate the keystore.
  • -validity 999999 — This says to make the keystore valid for 999,999 days.

For the keystore name, provide it with a name that makes sense. In theory, you should use a unique release keystore for each app, but it’s not required. For example, a puzzle game named “SwapIt” may have a keystore name such as swapit.keystore, but a more general release keystore could simply be release.keystore.

For alias, provide it with a similar sensible name, for example swapit.

With these changes, the line should look more like this:

keytool -genkey -v -keystore swapit.keystore -alias swapit -keyalg RSA -validity 999999

Now hit the return/enter key to execute the command. You’ll then be prompted for more information in a routine that will appear as follows in the command window:

Enter keystore password:  
Re-enter new password: 
What is your first and last name?
  [Unknown]:  YourFirstName YourLastName
What is the name of your organizational unit?
  [Unknown]:  Indie      
What is the name of your organization?
  [Unknown]:  Your Company Name
What is the name of your City or Locality?
  [Unknown]:  YourCity
What is the name of your State or Province?
  [Unknown]:  ST
What is the two-letter country code for this unit?
  [Unknown]:  US
Is CN=YourFirstName YourLastName, OU=Indie, O=Your Company Name, L=YourCity, ST=ST, C=US correct?
  [no]:  yes
Generating 1,024 bit RSA key pair and self-signed certificate (SHA1withRSA) with a validity of 999,999 days
	for: CN=YourFirstName YourLastName, OU=Indie, O=Your Company Name, L=YourCity, ST=ST, C=US
Enter key password for 
	(RETURN if same as keystore password):  
Re-enter new password: 
[Storing swapit.keystore]

The first password is the password for the overall keystore file. Next you’ll be asked for your first and last name (surname). The prompt for “organizational unit” is for companies with multiple departments like “Engineering” or “Development” and this value is not important for most Corona developers, but you need to still provide a value, such as “Development”. In addition, you’ll be prompted for your city, state/province, and country code.

At this point, you must type in yes to confirm the information. Finally, if desired, you can supply a different password to the individual alias entry, or simply press return/enter to use the same password associated with the keystore file.

When this is done, your keystore file will be in the folder where you ran the command.

Installing “keytool”

The keytool utility should be installed as part of JDK (Java Development Kit). This tutorial will not discuss actual installation of JDK, so if you’re new to this process, please read our corresponding guide.

On Mac, the keytool utility will be placed in a location such that you can just type keystore in the Terminal to run it. On Windows, this likely won’t be the case — when you installed the JDK, it was probably installed within a folder specific to the JDK version. For instance, on my Windows 7 computer, it’s located in:

C:\Program Files (x86)\Java\jdk1.8.0_05\bin

Because the keytool utility is located here, it’s tempting to simply change to this directory and type keytool ... directly, but if you update/reinstall JDK and your keystores are stored here, you’ll lose all of those you already created. As such, a better solution is to prefix the location of your Java install before the keytool command. Before doing so, you must set an environment variable called JAVA_HOME which will provide a shortcut that you can use. If you’re not familiar with this task, see this tutorial. Once it’s set, you can prefix it to the keytool command as follows:

%JAVA_HOME\bin\keytool ...

For instance, using the example keystore details from above, the command becomes this:

%JAVA_HOME\bin\keytool -genkey -v -keystore swapit.keystore -alias swapit -keyalg RSA -validity 999999

Building the App

To build with your release keystore, launch Corona SDK, load your app, and then build for Android (File → Build → Android…). In the Keystore dialog box, click on the Browse… button beside the Keystore pulldown menu. Navigate to where you saved your keystore file and select it from the dialog box, upon which you’ll be prompted to enter the keystore password.

Once it’s loaded, you’ll see that the Key Alias field is empty. Select the proper alias in this pulldown list and click the Build button. Corona will then prompt you to enter the alias password. Once entered correctly, you’ll be taken back to the build screen where you can hit Build again to build the app. Fortunately, for as long as you use this same release keystore/alias, you won’t need to re-enter the passwords each time.

Keyhashes and SHA1 Signatures

When working with third parties like Facebook or Google Play Game Services (GPGS), sometimes you’ll be asked to generate a value from your keystore. For Google Play Game Services, you must use a release keystore for this task. For Facebook, you can develop/test with a debug keystore, but you’ll eventually need to provide them with information for an app signed with a release keystore.

Both a keyhash (used by Facebook) and a SHA1 signature (used by GPGS) are short strings consisting of values that are calculated from the much larger keystore file. While these two are different values, the concept is the same — some standard math is performed on the values in the keystore to generate a unique value that cannot be easily reversed, helping ensure that the keystore hasn’t been altered by a hacker.

Generating a Keyhash

To generate the keyhash, you once again need to use the command line and enter a line which appears complex but in truth consists of just three commands:

keytool -exportcert -alias yourkeyalias -keystore yourkeystore.keystore | openssl sha1 -binary | openssl base64

The three commands taken separately are as follows:

  • keytool -exportcert -alias yourkeyalias -keystore yourkeystore.keystore
  • openssl sha1 -binary – uses the SHA1 method of calculating a signature, output as binary.
  • openssl base64 – outputs the data in Base64.

As you can see, these three commands are separated by pipe (|) characters. The first command runs and outputs its results, which in turn becomes the input for the second command. Then the second command outputs its results which become the input for the third command. This can cause potential issues because, if there’s even a slight problem in an earlier command, the error gets passed on to the next command rather than the expected data.  For instance, if you mis-type your password, this command series will not notify you but rather produce an SHA1 string based on the input of “Invalid Password”.

In any case, as noted earlier in this tutorial, this is not a copy-and-paste command — you must adjust -alias and -keystore to your specific values. When running this command using the keystore created above, the result is:

tZRNBKXmYKOa22HvFl57za4gvU0=

Note the = sign at the end — this indicates the end of the string and it is important.

Generating a SHA1 Signature

GPGS, in contrast, needs a text representation of the SHA1 output. Fortunately, the keytool utility can output this without any additional commands:

keytool -exportcert -alias swapit -keystore swapit.keystore -list -v

After you enter the password, the output will look something like this:

Alias name: swapit
Creation date: Aug 24, 2014
Entry type: PrivateKeyEntry
Certificate chain length: 1
Certificate[1]:
Owner: CN=YourFirstName YourLastName, OU=Indie, O=Your Company Name, L=YourCity, ST=ST, C=US
Issuer: CN=YourFirstName YourLastName, OU=Indie, O=Your Company Name, L=YourCity, ST=ST, C=US
Serial number: 53fa57f7
Valid from: Sun Aug 24 17:24:07 EDT 2014 until: Sun Jul 20 17:24:07 EDT 4752
Certificate fingerprints:
	 MD5:  66:22:E9:94:EA:14:EA:4A:06:EB:98:8B:DA:2B:25:D2
	 SHA1: B5:94:4D:04:A5:E6:60:A3:9A:DB:61:EF:16:5E:7B:CD:AE:20:BD:4D
	 Signature algorithm name: SHA1withRSA
	 Version: 3

In this output, the SHA1: line is the string of hex digits which you need to provide to GPGS when setting up your app, as well as the value you need to provide to Google when setting up your app there. Alternatively, if you need the SHA1 signature formatted as a string rather than a colon-separated hex string, use this command:

keytool -exportcert -alias swapit -keystore swapit.keystore | openssl sha1 -hex

Conclusion

Hopefully this tutorial has helped clarify and understand the Android signing process better. Remember these command lines and the familiarize yourself with the parameters, and Android signing will soon become a simple task.


Posted by . Thanks for reading...

11 Responses to “Tutorial: Understanding Android App Signing”

  1. Andreas

    Hi Rob,

    I haven’t done these steps for quite a while but I’ll have to do them in a few weeks again – so thanks a lot for this nice compilation of all the stuff that has to be done in a nutshell.

    Best,
    Andreas

    Reply
  2. undecode

    Rob, wonderful contribution.

    I remember back in the time having problems with this until i found a step-by-step guide to create a keystore to publish my app. This is really complete and will help new developers, also the additional information about keyhashes helps me in case google doesn’t recognize the one in the app automatically when using GPGS.

    Thanks

    Reply
  3. Mo

    The reason I said perfect not only because it is a fantastic tutorial but also because I was always affraid to touch the GPGS part (for leaderboard) with this I think I can attempt to add leaderboards to my apps in Android! Still scary but this explain a lot about the SHA1 business (man who came up with this stuff :)

    Thanks again.

    Mo

    Reply
  4. Danial

    I’ve never had to provide the SHA1 to get GPGS leaderboards to work for my Android apps I haven’t been asked to provide it, so I am confused.

    Reply
    • Rob Miracle

      If you upload your app to Google Play in Beta or Alpha mode before setting up the GPGS application, then it fetches the SHA1 signature from your uploaded APK (this is new, it didn’t use to be this way). But you can setup a GPGS application before you upload a .apk to Google Play. In which case you have to enter the SHA1 signature of the app’s release keystore.

      Reply
  5. Mo

    Hi Rob,

    Are you saying that IF we have apps already live on Google Play and wanted to add a leaderboard (GPGS) to them, we would not need to deal with all that SHA1 business?

    That would be cool! I was frankly scared to go thru those steps. Thanks God for your tutorial!

    Thanks,

    Mo

    Reply
    • Rob Miracle

      You still have to go through all the setup steps, but if you have uploaded the .apk first and then “link to the app” then it will get the SHA1 signature for you, so that at least saves you the pain of generating it form the command line.

      Rob

      Reply

Leave a Reply

  • (Will Not Be Published)