SIGNING ANDROID APPLICATIONS
Created: April 19, 2012

Given all the time and care you spend on developing your Android™ apps, the last thing you want is to have to worry about the integrity of your final product. Ensuring that the app you deliver to Google Play is the exact same app that your customers download–without fear of modification by others–is the primary reason Google requires that all Android apps be signed. Fortunately, the signing process itself is relatively simple. However, there are a number of implications that all Android app developers–particularly those not intimately familiar with the ins and outs of code signing–should be aware of.

Some definitions

To begin with, let's go over some basic terminology:

Public Key Cryptography
A cryptographic system that uses a pair of keys–one public and one private–where one key encrypts a message or signs an app while the other decrypts the encrypted message or verifies the app's signature. The two keys are strings of binary digits; for purposes of Android app signing, Google recommends that your keys be at least 2048 bits in length. Because of the way that the signing algorithm works, the private key must be kept private while the public key can be freely distributed. Note that for message encryption, you encrypt the message with the public key and decrypt it with the private key. For app signing, the reverse is true: you sign the app with the private key, and verify the signature using the public key.
Keystore
A repository (usually, an encrypted file) containing private keys and security certificates. You typically use a command-line tool called keytool to manipulate the keystore. Note that if you are using Eclipse or MOTODEV Studio, they employ keytool on your behalf; you don't have to invoke the command-line tools to either generate keys and certificates or sign your apps.
Certificate
An electronic document that uses a digital signature to connect a public key to an identity (of a person or corporation, typically). The identity is a set of information such as the name of a person or an organization, their address, and so forth. Certificates used to sign Android applications follow the X.509 standard; that standard defines the set of identity fields used within the certificate. Android uses the certificate both to identify the author of an app and to establish a trust relationship between apps that have both been signed using the same certificate. In addition to the public key and identity information, certificates also have a "validity period": a period of time during which the certificate is valid. Beyond this validity period, the certificate is considered invalid. Android developers apply their own certificates; unlike on some platforms, Google doesn't apply a certificate of its own to apps submitted to Google Play.

Certificates can be issued by a trusted source–a "Certificate Authority" or CA–or they can be user-generated. This latter form is often referred to as "self-signed". When used to sign an Android app, the certificate need not be issued by a CA. In fact, self-signed certificates are not only allowed but are typically what developers use to sign Android apps. As with your key pairs, you can use keytool to generate, display, import, and export digital certificates.

X.509 certificates are kept in files; install one by moving the file to the device and pointing the app that needs it to the certificate file.

Signature
A mathematical scheme that can verify the authenticity of a digital message or document. In practice, it is the result of a specific computation over the data being signed (an Android app, in this case) using a private key. By performing a second, related calculation using the public key, the signature, and the signed app, the integrity of the app can be validated. For Android, the algorithm used to create the signature is "SHA-1 with RSA encryption".

Inside a certificate

A certificate includes, among other things, the public key, the validity period, an indication of the algorithm used to apply the keys, and the "subject name": a structured text string that is organized into fields intended to identify the issuer of the certificate (often referred to as the "issuing entity"). The subject name string contains such fields as common name, organization name and unit, locality, state, and country. While part of the service a CA performs is to verify that subject name fields accurately reflect the entity requesting the certificate, when you create a self-signed certificate you can supply any values you like for these fields: the tools do no checking and there is no independent verification of their validity. Thus it is important to note that while the creator of a self-signed certificate can verify that it is one of theirs, a third party cannot rely on the subject name fields to prove certificate ownership. They can, however, prove that whoever owns the certificate signed the app. For its part Android doesn't actually concern itself with the fields that make up a certificate; when comparing two certificates, for instance, it simply treats them both as binary blobs. If the binary data is the same, it knows that the certificates are the same.

To see the certificate used to sign an Android app, you need only unzip the APK and issue the following command in a terminal window:

openssl pkcs7 -in <unzipped_apk_folder>/META-INF/<RSA_cert_file>.RSA -print_certs
		-inform DER -text

Here is the kind of thing you'll see by issuing the above command on an (unzipped) APK that was self-signed:

Certificate:
	Data:
		Version: 3 (0x2)
		Serial Number:
			01:2f:36:80:33:07
		Signature Algorithm: sha1WithRSAEncryption
		Issuer: O=Motorola Mobility, Inc., ST=CA, L=Sunnyvale, C=US, CN=Greg Wilson, OU=Developer Community Technical Services
		Validity
			Not Before: Apr  8 19:04:22 2011 GMT
			Not After : Apr  8 19:04:21 2041 GMT
		Subject: O=Motorola Mobility, Inc., ST=CA, L=Sunnyvale, C=US, CN=Greg Wilson, OU=Developer Community Technical Services
		Subject Public Key Info:
			Public Key Algorithm: rsaEncryption
			RSA Public Key: (1024 bit)
				Modulus (1024 bit):
					00:95:59:f2:f4:9e:86:e5:5a:ea:bc:80:5d:2a:d6:
					6d:b4:bd:40:c9:f7:c4:1f:cb:13:e5:a6:24:b5:fe:
					ff:84:18:46:ab:8d:3b:77:05:c2:ce:18:1a:5b:e5:
					f0:b4:85:99:f6:d7:fb:1f:84:81:df:b4:e0:89:ed:
					f8:2c:f7:6a:50:45:48:8d:5e:72:db:c2:de:b1:55:
					52:e8:48:b5:31:8b:53:8c:41:3b:a4:8d:f3:7e:48:
					fc:80:b1:3f:68:cb:d4:a1:e2:01:d5:64:64:7f:6a:
					d0:b3:10:4d:d0:fb:12:38:37:17:78:f8:1a:ae:5c:
					46:93:ce:0a:8c:e3:f3:17:37
				Exponent: 65537 (0x10001)
	Signature Algorithm: sha1WithRSAEncryption
		53:9f:0f:e6:50:60:e1:aa:4f:11:6b:3c:85:22:3a:67:5e:1e:
		c8:43:47:c9:f1:4f:ec:e1:2b:15:e2:85:d1:f6:7b:46:2e:74:
		e1:55:52:2c:ee:34:69:bf:96:df:7e:d2:16:a5:e6:e0:fd:20:
		6f:f2:84:d3:41:4b:be:b9:50:a7:82:52:33:7b:85:a9:16:13:
		8d:25:b6:02:77:42:00:6e:48:ae:fe:31:70:f2:f4:1c:21:aa:
		de:8b:0f:47:e4:d9:fc:bf:31:25:2e:5f:15:4f:4a:15:4b:d4:
		53:6b:e9:e1:04:18:82:9f:be:b1:59:5a:55:28:98:05:00:c1:
		bd:fb
-----BEGIN CERTIFICATE-----
MIICqTCCAhKgAwIBAgIGAS82gDMHMA0GCSqGSIb3DQEBBQUAMIGXMSAwHgYDVQQK
DBdNb3Rvcm9sYSBNb2JpbGl0eSwgSW5jLjELMAkGA1UECAwCQ0ExEjAQBgNVBAcM
CVN1bm55dmFsZTELMAkGA1UEBhMCVVMxFDASBgNVBAMMC0dyZWcgV2lsc29uMS8w
LQYDVQQLDCZEZXZlbG9wZXIgQ29tbXVuaXR5IFRlY2huaWNhbCBTZXJ2aWNlczAe
Fw0xMTA0MDgxOTA0MjJaFw00MTA0MDgxOTA0MjFaMIGXMSAwHgYDVQQKDBdNb3Rv
cm9sYSBNb2JpbGl0eSwgSW5jLjELMAkGA1UECAwCQ0ExEjAQBgNVBAcMCVN1bm55
dmFsZTELMAkGA1UEBhMCVVMxFDASBgNVBAMMC0dyZWcgV2lsc29uMS8wLQYDVQQL
DCZEZXZlbG9wZXIgQ29tbXVuaXR5IFRlY2huaWNhbCBTZXJ2aWNlczCBnzANBgkq
hkiG9w0BAQEFAAOBjQAwgYkCgYEAlVny9J6G5VrqvIBdKtZttL1AyffEH8sT5aYk
tf7/hBhGq407dwXCzhgaW+XwtIWZ9tf7H4SB37Tgie34LPdqUEVIjV5y28LesVVS
6Ei1MYtTjEE7pI3zfkj8gLE/aMvUoeIB1WRkf2rQsxBN0PsSODcXePgarlxGk84K
jOPzFzcCAwEAATANBgkqhkiG9w0BAQUFAAOBgQBTnw/mUGDhqk8RazyFIjpnXh7I
Q0fJ8U/s4SsV4oXR9ntGLnThVVIs7jRpv5bfftIWpebg/SBv8oTTQUu+uVCnglIz
e4WpFhONJbYCd0IAbkiu/jFw8vQcIareiw9H5Nn8vzElLl8VT0oVS9RTa+nhBBiC
n76xWVpVKJgFAMG9+w==
-----END CERTIFICATE-----

The actual certificate contents fall between the BEGIN CERTIFICATE and END CERTIFICATE lines, as you might guess. The "Subject:" and "Issuer:" lines, which look very similar to one another, show you the certificate's subject name fields. In order, these are showing the Organization name ("O="), the state ("ST="), the locality ("L="), the country ("C="), the common name ("CN="), and the organization unit ("OU="). Certificates can actually be chained together; when the subject and issuer lines differ, the certificate you are looking at is part of a chain (and is not the root of the chain). Self-signed certificates stand alone, and thus these two lines have the same value.

What are certificates for?

There are three main reasons people use certificates. Certificates can be used for transport-layer security (as with HTTPS; they serve to authenticate the server and, optionally, the client), as a digital identity, or for code signing. Certificates can either be "all purpose" or generated specifically for a particular purpose, such as for signing code. Because the individual generating a self-signed certificate can supply any values for the identity fields, a self-signed certificate is not a good choice to establish a digital identity; for that, a CA-issued certificate is needed. Self-signed certificates are ideal for signing Android apps, however: they can be freely generated, and as long as the private key is kept private, they can assure to a reasonable degree that the app being installed on an Android device has not been tampered with and is thus the app that the signing developer originally produced. As well, they can be used to establish that two apps, or an app and an update, signed by the same certificate, were produced by the same entity and thus should be allowed to interact.

Note that although app signing ensures that the app being installed is as it was when it was signed, it does not guarantee that the app being installed is the one the user intended to install. If you submit an Android app to Google Play, another developer cannot overwrite it with an altered version of your app–or a different app entirely–signed with a different key. They can, however, upload an app to Google Play with a similar name, description, icon, and the like with the intent of tricking end users into downloading it, thinking that it is yours. And, although difficult, it is possible for an unscrupulous developer to "crack" a signed Android application, make changes, re-sign it (with a different certificate), and upload it to Google Play. But without the private key used to sign the original app, they cannot overwrite the original, and they cannot create an update for the original.

The primary reason an Android app developer should care about certificates is for use during app signing. App signing certificates are generated and applied on your development computer and are not installed separately on your Android device. Your Android device may have certificates installed on it, but those are used to enforce transport-layer security and have nothing to do with app signing.

Why Android apps are signed

Android requires that all apps–development builds and release builds alike–installed on an Android device be signed. Why? There are a few reasons:

  • To provide some degree of assurance that an app is unaltered
  • To securely tie an app to its updates
  • To allow close ties between separate apps signed using the same certificate

For Android apps, there are additional benefits to code signing:

  • On Android, application signing is the first step to placing an application into its own application sandbox. The signing certificate helps to define which user ID is associated with a given application. Apps signed with different certificates run under different user IDs, and cannot directly access each other's data. Application signing thus ensures that one application can only interact with another through a well-defined IPC mechanism.
  • Two apps signed with the same certificate can be run in the same process. An APK has the option to specify in its manifest that it will share its UID with other similarly signed APKs. If the certificate (or, more accurately, the public key in the certificate) used to sign one app matches the one used to sign another app on the same device, those apps will be run in the same process and will have access to each other's data.
  • Apps can declare security permissions at the Signature protection level, allowing some access by apps signed with the same key while maintaining distinct UIDs and application sandboxes.

The requirement that all apps be signed extends to apps under development, as well as to the release versions of your apps. Both at app installation, and again when the app is run, the device checks the app for a signature. This check cannot be bypassed by "side-loading" apps or downloading apps from other than Google Play. Therefore, all apps must be signed. Fortunately for developers the tools automatically generate and apply a debug certificate to development builds; you need only get involved when you create release versions of your apps. When you are ready to release an app, you sign it with a suitable private key. Note that you cannot publish an app that has been signed with a debug key.

You can publish, but users can't install, an app that is signed using a certificate that has expired. Android will, however, allow you to run an app that has already been installed even if the certificate has since expired. Related to this is the fact that app updates must be signed using the same certificate as the app to which they apply. Thus when creating a certificate to use for app signing make sure that it has a sufficiently long validity period–Google recommends a minimum of 25 years–to last for not only the projected lifetime of the app itself, but also any updates you may issue. This is a very important point, because after the certificate expires, users can no longer install the app and can no longer install any updates.

Signing: the basic steps

The basic steps for signing an Android app for release are:

  1. Obtain or create a public/private key pair and a certificate that uses the public key. From the command-line you can use keytool to create your keys and certificates. From within MOTODEV Studio, you can use the Application Signing Tool view to create and manage your keys and certificates. Note that once you have these, you can use them to sign multiple apps and updates. You need not (and likely should not) create new keys and/or certificates for each app or build.
  2. Build your app in release mode (if you are using the command-line) or export an unsigned version of your app (if you are using Eclipse; right-click your project in the Package Explorer and select Android Tools > Export Unsigned Application Package).
  3. Sign your app with your private key using jarsigner. If you are using MOTODEV Studio you can use the Application Signing Tool view to sign an unsigned APK.
  4. Use zipalign to align any uncompressed data on 4-byte boundaries (for performance optimization; this is not strictly part of the signing process).

If you are using Eclipse or MOTODEV Studio for Android you can employ a wizard that walks you through steps 1-3 (or steps 2-3, if you already have a key pair and certificate). Right-click your project, select Export, and then select Android > Export Android Application (or Android > Export Android Application using MOTODEV Studio for Android).

The following shows the process for signing and aligning an APK for release:

signing_flow.png

The entire process is detailed in Signing Your Applications in the Android developer documentation. Note that the Android documentation refers to "Release Mode" and "Debug Mode" but although on the command line there are "debug" and "release" options for use with the ant command, there isn't an Eclipse UI for making any such mode switch. Instead, when developing and debugging you let the tools build your APK for you, resulting in an APK signed with the appropriate debug certificate. Then, when you are ready to release your app, you simply follow the procedure outlined above after generating your APK.

Inside the signed APK

The act of signing an Android app (with either a debug or release certificate) causes a "META-INF" folder to be added to your APK. Within this folder you'll find three files:

  • *.RSA is a "signature block file". This is not human-readable. It contains both the digital signature for the APK that was generated with your private key as well as the certificate containing your public key.
  • MANIFEST.MF is the "manifest file" (not to be confused with AndroidManifest.xml; MANIFEST.MF is strictly for signing purposes). The manifest file contains an entry for each individual file that makes up the APK; each entry lists the full name of the file and a digest, or hash, of the contents of the file. For instance, here is a simple manifest file:
    Manifest-Version: 1.0
    Created-By: 1.0 (Android)
    
    Name: res/layout/main.xml
    SHA1-Digest: Xal5w1XkBBgw1JtbLohBa8RxDDk=
    
    Name: res/drawable-ldpi/icon.png
    SHA1-Digest: i7vxaosoiS+9HzKB7ZgIsXMYRLY=
    
    Name: AndroidManifest.xml
    SHA1-Digest: MeD1XtT3XBG9kND9GNDGxsF+jMs=
    
    Name: res/drawable-mdpi/icon.png
    SHA1-Digest: 7Ft/Rirt+l/JRX2KjDREScdbCZk=
    
    Name: resources.arsc
    SHA1-Digest: 6Px+Iy7gIbejFN0gdtBwzsSGrGA=
    
    Name: classes.dex
    SHA1-Digest: ddT6Ngs12f5Yy7RTc9HDfA8dJ+k=
    
    Name: res/drawable-hdpi/icon.png
    SHA1-Digest: Vj/qhxk8ic8FE0/kT6E3vgRJ4mE=
    
  • *.SF is the "signature file". It looks a lot like the manifest file, but the digest values here are computed from the manifest entries, rather than from the files themselves. The signature file also includes a digest value for the entire manifest. Here is the signature file corresponding to the manifest file shown above:
    Signature-Version: 1.0
    Created-By: 1.0 (Android)
    SHA1-Digest-Manifest: pvfRpfQ8KyIHVAIPrVkV82K8Hac=
    
    Name: res/layout/main.xml
    SHA1-Digest: aQj8hpWCMdsFwVuVLtqolo9seCQ=
    
    Name: AndroidManifest.xml
    SHA1-Digest: 1tsqLweogdhgQzuArLvP1cfytb0=
    
    Name: res/drawable-ldpi/icon.png
    SHA1-Digest: Z/yxmMxGRNbFUkjqWONvJQH5rQw=
    
    Name: res/drawable-mdpi/icon.png
    SHA1-Digest: iR1AGdcgDutAX/5xyl92TWcEJuw=
    
    Name: resources.arsc
    SHA1-Digest: v02xf09R9z3nH5TxsrfuA4+SAcA=
    
    Name: classes.dex
    SHA1-Digest: Rdr9d2YMla8EbiFcH4K7MnJ7VCM=
    
    Name: res/drawable-hdpi/icon.png
    SHA1-Digest: 3vv9derC/UrLpiam9i2Yo16eHXw=
    

During verification, the digest values in the manifest file and the signature file can be checked to ensure that the contents of the APK have not changed.

Signing tips

The debug certificate that Android generates for you has a fixed password and predefined certificate fields. For details, see Signing in Debug Mode in the Android developer documentation.

When creating your keys and certificates, keep in mind that Android app updates only work if they have been signed with the same certificate (or set of certificates) as the app being updated. During installation of the update, Android compares the certificate in the update with the certificate in the installed version of the app and only applies the update if the certificates match exactly. Because of this, it is extremely important that you save your keys and certificates (by saving a copy of your keystore) for use when signing your app updates. Once lost, the keys cannot be recovered–and there is currently no way to migrate a published app to a new certificate.

Because your updates must be signed with the same certificate as the original, make sure that your certificates have a validity period that exceeds the expected lifespan of the app and all its updates. Once the key's validity period expires, the app will continue to run (the validity period is only checked at installation) but new updates won't be accepted. Google recommends that your certificates be valid for at least 25 years (and Google Play will not accept an app unless its signing certificates are valid until at least October 22, 2033). Note that certificates generated by a CA are usually only valid for a year or so, because their business model relies on continued verification. This is another reason to use a self-signed certificate over one issued by a CA.

When creating your keys, be sure to use strong passwords. Keep those passwords secret and, except within an organization where there are multiple developers who need to publish updates or apps using a single certificate, don't give your private key to anyone else. All of the security benefits that Android provides can be negated if your private keys are not kept private. If you are the only one holding the private key, you can prove that an app was signed by you and not modified by anyone else. And the market to which you publish your updates can be assured that they only come from you.

Wrapping up

The mechanics of signing an Android application for release to your customers are relatively simple, but a clear understanding of how you should create your certificates is critical to ensuring that you don't run into serious trouble down the road. When it is time to issue an app update is not the best time to discover that the keys you used to sign the original app cannot be found, or that the certificate has expired and cannot be used to sign the update. Setting a proper certificate expiration date, creating keys of a proper length, and keeping your private keys truly private will go a long way towards guaranteeing the integrity of your apps and preserving your ability to maintain and update those apps long into the future.

 

-Greg Wilson
Motorola Mobility, Inc.

 

Created: April 19, 2012

ECCN 5E991.NR: In accordance with United States Export Administration Regulations (EAR), and specifically the Commerce Control List (CCL), this item has been classified 5E991.NR. Export or re-export of this commodity and compliance with the U.S. Export Administration Regulations is ultimately the responsibility of the exporter. For more detailed information related to export or re-export of this item, please consult the EAR at http://www.access.gpo.gov/bis/ear/ear_data.html.

print the page
other documentation
Resources
Mobilizing your apps (PDF)
.................................................
Best Practices for Android Encryption (PDF)
.................................................
Designing HTML5 Apps
.................................................
Understanding Texture Compression
.................................................
Bluetooth Low Energy API's
.................................................
Indoor location manager
.................................................
Enterprise Device Management
.................................................
Signing Android apps
.................................................
Using AES in Android
.................................................
Motodev Core Plugins
Building
.................................................
Menu and View alternatives
.................................................