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