Manually Signing the APK
- PDF for offline use:
Let us know how you feel about this.
last updated: 2016-11
After the application has been built for release, the resulting APK (Android application package) with a private key and zipalign it so that it is ready for Android to run. This process can be accomplished outside the IDE by manually completing the following steps:
Create a Private Key – This step needs to be performed only once. A private key is necessary to digitally sign the APK. After the private key has been prepared, this step can be skipped for future release builds.
Sign the APK – This step involves signing the APK with the private key that was created in the previous step.
Zipalign the APK – Zipalign is an optimization process that is performed on an application. It enables Android to interact more efficiently with the APK at runtime. Xamarin.Android conducts a check at runtime, and will not allow the application to run if the APK has not been zipaligned.
Create a Private Keystore
A keystore is a database of security certificates that is created by using the program keytool from the Java SDK. A keystore is critical to publishing a Xamarin.Android application, as Android will not run applications that have not been digitally signed.
During development, Xamarin.Android uses a debug keystore to sign the application, which allows the application to be deployed directly to the emulator or to devices configured to use debuggable applications. However, this keystore is not recognized as a valid keystore for the purposes of distributing applications.
For this reason, a private keystore must be created and used for signing applications. This is a step that should only be performed once, as the same key will be used for publishing updates and can then be used to sign other applications.
It is important to protect this keystore. If it is lost, then it will not be possible to publish updates to the application with Google Play. The only solution to the problem caused by a lost keystore would be to create a new keystore, re-sign the APK with the new key, and then submit a new application. Then the old application would have to be removed from Google Play. Likewise, if this new keystore is compromised or publically distributed, then it is possible for unofficial or malicious versions of an application to be distributed.
Create a New Keystore
Creating a new keystore requires the command line tool
from the Java SDK. The following snippet is an example of how to use
<my-filename> with the file name for the keystore
<key-name> with the name of the key within the keystore):
$ keytool -genkeypair -v -keystore <filename>.keystore -alias <key-name> -keyalg RSA \ -keysize 2048 -validity 10000
The first thing that keytool will ask for is the password for the
keystore. Then it will ask for some information to help with creating
the key. The following snippet is an example of creating a new key
publishingdoc that will be stored in the file
$ keytool -genkeypair -v -keystore xample.keystore -alias publishingdoc -keyalg RSA \ -keysize 2048 -validity 10000 Enter keystore password: Re-enter new password: What is your first and last name? [Unknown]: Ham Chimpanze What is the name of your organizational unit? [Unknown]: NASA What is the name of your organization? [Unknown]: NASA What is the name of your City or Locality? [Unknown]: Cape Canaveral What is the name of your State or Province? [Unknown]: Florida What is the two-letter country code for this unit? [Unknown]: US Is CN=Ham Chimpanze, OU=NASA, O=NASA, L=Cape Canaveral, ST=Florida, C=US correct? [no]: yes Generating 2,048 bit RSA key pair and self-signed certificate (SHA1withRSA) with a validity of 10,000 days for: CN=Ham Chimpanze, OU=NASA, O=NASA, L=Cape Canaveral, ST=Florida, C=US Enter key password for <publishingdoc> (RETURN if same as keystore password): Re-enter new password: [Storing xample.keystore]
To list the keys that are stored in a keystore, use the keytool with
$ keytool -list -keystore xample.keystore
Sign the APK
This technique involves signing the APK file outside of the IDE. The signing is performed at the command line, but can be automated easily by using a scripting language. To manually sign an APK:
Locate the unsigned APK, as shown earlier .
Sign the APK using jarsigner . Once the release APK is built, it is signed by using the jarsigner tool from the Java SDK and the private keystore that was created above. The following shows how to sign an APK by using jarsigner and the key
publishingdocthat is contained in a keystore file named xample.keystore :
$ jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 \ -keystore xample.keystore mono.samples.helloworld.apk publishingdoc
Zipalign the APK
After an application has been signed, it is important to optimize the APK file. To do this, use the zipalign tool from the Android SDK. The zipalign tool will restructure the resources in an APK along 4-byte boundaries. This alignment allows Android to quickly load the resources from the APK, increasing the performance of the application. Xamarin.Android will conduct a run-time check to determine if the APK has been zipaligned. If the APK is not zipaligned, then the application will not run.
The follow command will use the signed APK and produce a signed, zipaligned APK called helloworld.apk that is ready for distribution.
$ zipalign -f -v 4 mono.samples.helloworld-Signed.apk helloworld.apk
Signing the APK will undo the optimization that is performed by *zipalign. For this reason, it is important to first sign before using *zipalign.
Using Powershell to Automate APK Signing
Manually signing an APK can prove to be a tedious and error-prone process, and having
to embed the password for the keystore inside the .
csproj file does pose
security concerns. On Windows, one possible solution to this is to create a PowerShell
script that can be used to compile the APK, and then sign it at the command line. Here
is an example of what such a PowerShell script might look like:
# First clean the Release target: msbuild.exe HelloWorld.csproj /p:Configuration=Release /t:Clean # Now build the project, using the Release target. msbuild.exe HelloWorld.csproj /p:Configuration=Release /t:PackageForAndroid # At this point there is only the unsigned APK - sign it. # The script will pause here as jarsigner prompts for the password. # It is possible to provide they keystore password for jarsigner.exe by adding # an extra command line parameter -storepass, for example: # -storepass <MY\_SECRET\_PASSWORD> # If this script is to be checked in to source code control then it is not # recommended to include the password as part of this script. & 'C:\Program Files\Java\jdk1.6.0\_24\bin\jarsigner.exe' -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore ./xample.keystore -signedjar ./bin/Release/mono.samples.helloworld-signed.apk ./bin/Release/mono.samples.helloworld.apk publishingdoc # Now zipalign it. The -v parameter tells zipalign to verify the APK afterwards: & 'C:\Program Files\Android\android-sdk\tools\zipalign.exe' -f -v 4 ./bin/Release/mono.samples.helloworld-signed.apk ./helloworld.apk`