Signing Android Application

All Android apps (.apk files) must be digitally signed prior to installation on a device and uploading to Android Play store. The embedded certificate can be self-signed and valid for 25+ years. No certification authority needed so the vendor identification is not trusted. 

App signing on Android is used to:

  • Ensure the authenticity of the author on updates
  • Establish trust relationship among apps signed with the same key (share permissions, UID, process)
  • Make app contents tamper-resistant

An app can be signed with multiple keys. If the key is lost or expired, there is no way to update the application

Signing Your First Application

In Android Studio,  click build -> generate signed apk

First time you need to create a new keystore – set the password and save it in a safe place

After creating the keystore, select the key to generate signed APK

 

Signing Multiple Apps

You can sign as many apks as you like with the same key. Each application run with a different user id. If you want to run your applications with the same UID (so you can share resources between them), add shared user id (android:sharedUserId=”mycompany.myapp) to the manifest file of each app:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.app2" 
    android:sharedUserId="mycompany.myapp">

    <application
    ....

If you run both apps, you will see the same user id (u0_a75):

 

Signing Application with the Platform Keys

If you are a device vendor and you want to add a system application from the play store, you need to sign that application with the same keys you have signed the ROM.

The keys are located in: build/target/product/security :

  • platform.pk8
  • platform.x509.pem

To use Android Studio for apk signing you need a keystore. To create one I found the script here

Download and put the script in one of the folders in the PATH

To generate keystore use the following command:

# keytool-imp -k my.keystore -p mypass -pk8 platform.pk8 -cert platform.x509.pem -alias platform

This command create a keystore my.keystore protected with password mypass and a key platform with private and public pair (pk8, x509)

To make your application runs with system user add android:sharedUserId=“android.uid.system” to the AndroidManifest.xml file :

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.developer.mysystemapp" android:sharedUserId="android.uid.system">
...

 

Now use Android Studio to sign the APK:

Go to Build -> Generate Signed APK

Fill the keysore file, the keystore password, the key name (platform) and the key password.

Install the apk

# adb install app-release.apk

If you run the app, using adb shell ps -A you should see it running with system privileges

 

Signing Application With Other Trusted key

You can generate a new key for trusted customers and let the them sign its apps with it.

Use the readme file in build/target/product/security to create a new key pair , use the above instruction to make a keystore to sign apks.

I created vendortest.pk8, vendortest.x509.pem and added them to the keystore vendor.keystore

Add a section to the file system/sepolicy/private/mac_permissions.xml:

    <signer signature="@VENDORTEST" >
       <seinfo value="vendortest" />
    </signer>

 

To create an SE Android label we need to define a new application type – vend_app

edit the following SE Linux files: (in aosp/system) – all published to github

./sepolicy/prebuilts/api/26.0/nonplat_sepolicy.cil
./sepolicy/prebuilts/api/26.0/public/update_engine.te
./sepolicy/prebuilts/api/26.0/public/domain.te
./sepolicy/prebuilts/api/26.0/public/kernel.te
./sepolicy/prebuilts/api/26.0/public/priv_app.te
./sepolicy/prebuilts/api/26.0/public/vend_app.te
./sepolicy/prebuilts/api/26.0/private/domain.te
./sepolicy/prebuilts/api/26.0/private/app.te
./sepolicy/prebuilts/api/26.0/private/priv_app.te
./sepolicy/prebuilts/api/26.0/private/priv_app.te
./sepolicy/prebuilts/api/26.0/private/vend_app.te
./sepolicy/prebuilts/api/26.0/private/storaged.te
./sepolicy/prebuilts/api/26.0/private/logd.te
./sepolicy/prebuilts/api/26.0/private/seapp_contexts
./sepolicy/public/update_engine.te
./sepolicy/public/domain.te
./sepolicy/public/priv_app.te
./sepolicy/public/vend_app.te
./sepolicy/private/domain.te
./sepolicy/private/app.te
./sepolicy/private/priv_app.te
./sepolicy/private/vend_app.te
./sepolicy/private/compat/26.0/26.0.cil
./sepolicy/private/storaged.te
./sepolicy/private/logd.te
./sepolicy/private/seapp_contexts
./sepolicy/tests/treble_sepolicy_tests.py

generate a key for vendor customers and in the file seapp_contexts add the following line:

user=_app seinfo=vendortest domain=vend_app type=app_data_file

Now send the keystore to any customer you trust. Signing an APK with it to get extra permissions defined in your SE policy

if you run the customer app signed with that key you can see the new label using ps -AZ

 

Tagged , ,