1.前言
上篇《Android Automotive 14(2)多屏模拟器》讲到配置好模拟器,这篇文章将记录一下对于车机系统应用,
如何从零开始制作系统平台签名文件,并转换为Android Studio
使用的.jks
文件。
2.分析
AAOS源码的系统应用,一般都是通过Android.mk或者Android.bp 来编译的。
例如原生CarSettings
源码目录结构如下:
APK的打包,是在make的过程中完成的,编译完成就进行了系统签名。
Makefile
...
android_app {
name: "CarSettings",
overrides: ["Settings"],
platform_apis: true,
certificate: "platform",
....
Android.bp中certificate
值为platform,platform_apis
值为true,以上信息代表可以使用系统平台的一些隐藏API,并且权限等级比较高。
这种源码source并不是gradle编译结构,当需要频繁的推包或者安装验证时,依赖频繁make,调试效率不是很高。
是否可以直接用Android Studio
来开发编译和调试车机系统应用呢?答案是肯定。
但是,汽车应用出于驾驶安全等考虑,一般要想获得一些车身传感器相关的状态,
比如CarService
中的空调温度,车门车窗状态等等,是需要系统平台签名,才能访问API。
所以,我们要制作一个Android Studio
能用的系统平台签名,就可以很方便的进行车机系统应用开发了。
3.签名
在制作签名文件之前,我们先了解一下,系统有哪些签名。
AAOS14 的签名文件目录:
shell
user@ubuntu:~/code/aosp/build/target/product/security$ ls
Android.bp bluetooth.x509.pem cts_uicc_2021.x509.pem media.x509.pem platform.pk8 sdk_sandbox.pk8 shared.x509.pem
Android.mk BUILD.bazel fsverity-release.x509.der networkstack.pk8 platform.x509.pem sdk_sandbox.x509.pem testkey.pk8
bluetooth.pk8 cts_uicc_2021.pk8 media.pk8 networkstack.x509.pem README shared.pk8 testkey.x509.pem
每个密钥都包含两个文件:一个是扩展名为 .x509.pem
的证书,另一个是扩展名为 .pk8
的私钥。
阅读README文件,系统主要有如下几组签名,同时注明了生成的参数方法:
Text
key generation
--------------
The following commands were used to generate the test key pairs:
development/tools/make_key testkey '/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/emailAddress=android@android.com'
development/tools/make_key platform '/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/emailAddress=android@android.com'
development/tools/make_key shared '/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/emailAddress=android@android.com'
development/tools/make_key media '/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/emailAddress=android@android.com'
development/tools/make_key cts_uicc_2021 '/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/emailAddress=android@android.com'
官方文档对于key的解释,参照文档:
每组签名用途不同,进一步解释理解就是:
- platform 签名
- 用途:platform签名主要用于系统核心应用,这些应用直接与Android操作系统紧密集成,并执行关键的系统级功能。
- 特性 :
- 在
AndroidManifest.xml
中通过设置android:sharedUserId="android.uid.system"
表明该应用属于系统进程组,拥有更高的权限。 - 使用platform签名的应用程序通常运行在system UID下,可以直接访问受保护的API和资源,并且可以和其他system用户ID下的应用共享数据。
- 由于这类应用的安全敏感性,它们必须使用由设备制造商或系统开发者持有的私钥进行签名。
- 在
- media 签名
- 用途:media签名主要应用于与媒体处理和下载服务相关的系统组件,比如默认的媒体播放器、下载管理器等。
- 特性 :
- 同样需要在manifest文件中声明特定的共享用户ID,即
android:sharedUserId="android.media"
。 - 这类应用同样享有较高的权限,允许它们执行与多媒体处理相关的核心操作,例如读取和写入多媒体内容,以及管理网络下载任务等。
- media签名应用虽然不如platform签名应用权限高,但仍然具有超出普通第三方应用的特殊权限。
- 同样需要在manifest文件中声明特定的共享用户ID,即
- shared 签名
- 用途:shared签名是用于那些需要与其他特定系统进程(如home屏幕或者联系人应用)之间共享数据和资源的应用。
- 特性 :
- 设置
android:sharedUserId="android.uid.shared"
后,应用会以同一个用户ID运行,从而能够互相访问彼此的数据目录。 - shared签名的应用一般不涉及最底层的系统服务,而是针对系统内部具有一定协作关系的服务或者组件提供数据共享能力。
- 设置
- testkey 签名
- 用途:testkey是Android编译系统中的默认签名密钥,当一个APK没有明确指定LOCAL_CERTIFICATE变量时,系统会使用testkey对其进行签名。由于testkey是公开且容易获取的,因此它并不适用于正式发布或安全要求高的应用。
AAOS14源码API34默认的keys.conf
配置:
源码路径Z:\aosp\system\sepolicy\prebuilts\api\34.0\private\keys.conf
conf
[@PLATFORM]
ALL : $DEFAULT_SYSTEM_DEV_CERTIFICATE/platform.x509.pem
[@SDK_SANDBOX]
ALL : $MAINLINE_SEPOLICY_DEV_CERTIFICATES/sdk_sandbox.x509.pem
[@BLUETOOTH]
ALL : $MAINLINE_SEPOLICY_DEV_CERTIFICATES/bluetooth.x509.pem
[@MEDIA]
ALL : $DEFAULT_SYSTEM_DEV_CERTIFICATE/media.x509.pem
[@NETWORK_STACK]
ALL : $MAINLINE_SEPOLICY_DEV_CERTIFICATES/networkstack.x509.pem
[@SHARED]
ALL : $DEFAULT_SYSTEM_DEV_CERTIFICATE/shared.x509.pem
# Example of ALL TARGET_BUILD_VARIANTS
[@RELEASE]
ENG : $DEFAULT_SYSTEM_DEV_CERTIFICATE/testkey.x509.pem
USER : $DEFAULT_SYSTEM_DEV_CERTIFICATE/testkey.x509.pem
USERDEBUG : $DEFAULT_SYSTEM_DEV_CERTIFICATE/testkey.x509.pem
可以看出,这里取决于变量DEFAULT_SYSTEM_DEV_CERTIFICATE
定义。
进一步查看,源码路径Z:\aosp\build\make\core\config.mk
mk
# The default key if not set as LOCAL_CERTIFICATE
ifdef PRODUCT_DEFAULT_DEV_CERTIFICATE
DEFAULT_SYSTEM_DEV_CERTIFICATE := $(PRODUCT_DEFAULT_DEV_CERTIFICATE)
else
DEFAULT_SYSTEM_DEV_CERTIFICATE := build/make/target/product/security/testkey
endif
.KATI_READONLY := DEFAULT_SYSTEM_DEV_CERTIFICATE
源码路径Z:\aosp\build\make\core\sysprop.mk
mk
# The "test-keys" tag marks builds signed with the old test keys,
# which are available in the SDK. "dev-keys" marks builds signed with
# non-default dev keys (usually private keys from a vendor directory).
# Both of these tags will be removed and replaced with "release-keys"
# when the target-files is signed in a post-build step.
ifeq ($(DEFAULT_SYSTEM_DEV_CERTIFICATE),build/make/target/product/security/testkey)
BUILD_KEYS := test-keys
else
BUILD_KEYS := dev-keys
endif
所以,源码给了OEM厂商去配置定义自己的key,未做任何配置,默认就使用的testkey。
也可以用下面命令方法获得当前系统默认值:
shell
# 在源码路径下输入:
user@ubuntu:~/code/aosp$ get_build_var DEFAULT_SYSTEM_DEV_CERTIFICATE
build/make/target/product/security/testkey
# 在模拟器下面
emulator_car64_x86_64:/ # getprop |grep build.tags
[ro.bootimage.build.tags]: [test-keys]
[ro.build.tags]: [test-keys]
[ro.odm.build.tags]: [test-keys]
[ro.product.build.tags]: [test-keys]
[ro.system.build.tags]: [test-keys]
[ro.system_dlkm.build.tags]: [test-keys]
[ro.system_ext.build.tags]: [test-keys]
[ro.vendor.build.tags]: [test-keys]
[ro.vendor_dlkm.build.tags]: [test-keys]
源码路径Z:\aosp\system\sepolicy\prebuilts\api\34.0\private\mac_permissions.xml
其中,定义了应用程序的MAC(Mandatory Access Control)权限规则,即根据签名证书来控制应用可以访问哪些特定的安全上下文和资源。
xml
<!-- Platform dev key in AOSP -->
<signer signature="@PLATFORM" >
<seinfo value="platform" />
</signer>
<!-- Sdk Sandbox key -->
<signer signature="@SDK_SANDBOX" >
<seinfo value="sdk_sandbox" />
</signer>
<!-- Bluetooth key in AOSP -->
<signer signature="@BLUETOOTH" >
<seinfo value="bluetooth" />
</signer>
<!-- Media key in AOSP -->
<signer signature="@MEDIA" >
<seinfo value="media" />
</signer>
<signer signature="@NETWORK_STACK" >
<seinfo value="network_stack" />
</signer>
了解完以上这些源码和配置信息,对Android系统签名也有个大概了解;
现在我们要做的就是拿到platform签名,并且在应用中添加android:sharedUserId="android.uid.system"
配置。
4.制作
主要利用keytool
和openssl
,将系统的platform.pk8
和platform.x509.pem
,转化成Android Studio
可以使用的keystore文件,也就是格式为.jks
的文件。
详细步骤如下:
shell
# 1.进入key目录
code/aosp/build/make/target/product/security
# 2.根据platform.pk8文件,生成platform.pem文件
openssl pkcs8 -inform DER -nocrypt -in platform.pk8 -out platform.pem
# 3.根据platform.x509.pem文件,生成platform.p12文件,密码和alias名都配置成aaosdemo
openssl pkcs12 -export -in platform.x509.pem -out platform.p12 -inkey platform.pem -password pass:aaosdemo -name aaosdemo
# 4.根据platform.p12文件,生成platform.jks,密码和alias名都配置成aaosdemo
keytool -importkeystore -deststorepass aaosdemo -destkeystore ./platform.jks -srckeystore ./platform.p12 -srcstoretype PKCS12 -srcstorepass aaosdemo
调试打印信息如下:
scss
# 打印证书命令:
# keytool -printcert -v -file platform.x509.pem
# keytool -list -v -keystore platform.jks
user@ubuntu:~/code/aosp/build/make/target/product/security$ keytool -list -v -keystore platform.jks
Enter keystore password:
Keystore type: PKCS12
Keystore provider: SUN
Your keystore contains 1 entry
Alias name: aaosdemo
Creation date: Jan 28, 2024
Entry type: PrivateKeyEntry
Certificate chain length: 1
Certificate[1]:
Owner: EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US
Issuer: EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US
Serial number: b3998086d056cffa
Valid from: Tue Apr 15 15:40:50 PDT 2008 until: Sat Sep 01 15:40:50 PDT 2035
Certificate fingerprints:
SHA1: 27:19:6E:38:6B:87:5E:76:AD:F7:00:E7:EA:84:E4:C6:EE:E3:3D:FA
SHA256: C8:A2:E9:BC:CF:59:7C:2F:B6:DC:66:BE:E2:93:FC:13:F2:FC:47:EC:77:BC:6B:2B:0D:52:C1:1F:51:19:2A:B8
Signature algorithm name: MD5withRSA (disabled)
Subject Public Key Algorithm: 2048-bit RSA key
Version: 3
Extensions:
#1: ObjectId: 2.5.29.35 Criticality=false
AuthorityKeyIdentifier [
KeyIdentifier [
0000: 4F E4 A0 B3 DD 9C BA 29 F7 1D 72 87 C4 E7 C3 8F O......)..r.....
0010: 20 86 C2 99 ...
]
[EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US]
SerialNumber: [ b3998086 d056cffa]
]
#2: ObjectId: 2.5.29.19 Criticality=false
BasicConstraints:[
CA:true
PathLen: no limit
]
#3: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 4F E4 A0 B3 DD 9C BA 29 F7 1D 72 87 C4 E7 C3 8F O......)..r.....
0010: 20 86 C2 99 ...
]
]
*******************************************
*******************************************
Warning:
<aaosdemo> uses the MD5withRSA signature algorithm which is considered a security risk and is disabled.
5.配置
生成platform.jks
文件后,直接配置Android Studio
,调试应用。
- 1.在应用的
AndroidManifest.xml
加入android:sharedUserId="android.uid.system"
- 2.
build.gradle
加入signingConfigs
groovy
android {
...
signingConfigs {
aaos_platform {
storeFile file('platform.jks')
storePassword 'aaosdemo'
keyAlias 'aaosdemo'
keyPassword 'aaosdemo'
}
}
buildTypes {
release {
signingConfig signingConfigs.aaos_platform
...
}
debug {
signingConfig signingConfigs.aaos_platform
}
}
...
}
完成上述配置,点击运行,就可以直接安装到模拟器了。
通过运行前后对比,可以看出:
shell
# 未导入前,普通进程以a177 显示
emulator_car64_x86_64:/ $ ps -A |grep com.example.aaos
u10_a177 3214 370 13834132 134272 0 0 S com.example.aaos
#导入后,以System进程显示
emulator_car64_x86_64:/ $ ps -A |grep com.example.aaos
u10_system 3748 370 13832552 137928 0 0 S com.example.aaos
应用的process信息u10_system
已经变成system了,证明导入成功,接下来就可以导入系统一些支持的jar包,进行下一步的系统API的调用了。
6.总结
综上所述,完成了从零开始制作系统平台签名文件,并转换为Android Studio
使用的.jks
文件,为后续车机系统应用调试做好准备。
如果你喜欢我的文章,欢迎关注我的微信公众号阿坤iKun
,关注不迷路,我是练习时长两年半的阿坤iKun
,下期再见!
参考资料: