Android Automotive 14(3)车机应用系统平台签名

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/[email protected]'
  development/tools/make_key platform      '/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/[email protected]'
  development/tools/make_key shared        '/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/[email protected]'
  development/tools/make_key media         '/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/[email protected]'
  development/tools/make_key cts_uicc_2021 '/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/[email protected]'

官方文档对于key的解释,参照文档

每组签名用途不同,进一步解释理解就是:

  1. platform 签名
    • 用途:platform签名主要用于系统核心应用,这些应用直接与Android操作系统紧密集成,并执行关键的系统级功能。
    • 特性
      • AndroidManifest.xml中通过设置android:sharedUserId="android.uid.system"表明该应用属于系统进程组,拥有更高的权限。
      • 使用platform签名的应用程序通常运行在system UID下,可以直接访问受保护的API和资源,并且可以和其他system用户ID下的应用共享数据。
      • 由于这类应用的安全敏感性,它们必须使用由设备制造商或系统开发者持有的私钥进行签名。
  2. media 签名
    • 用途:media签名主要应用于与媒体处理和下载服务相关的系统组件,比如默认的媒体播放器、下载管理器等。
    • 特性
      • 同样需要在manifest文件中声明特定的共享用户ID,即android:sharedUserId="android.media"
      • 这类应用同样享有较高的权限,允许它们执行与多媒体处理相关的核心操作,例如读取和写入多媒体内容,以及管理网络下载任务等。
      • media签名应用虽然不如platform签名应用权限高,但仍然具有超出普通第三方应用的特殊权限。
  3. shared 签名
    • 用途:shared签名是用于那些需要与其他特定系统进程(如home屏幕或者联系人应用)之间共享数据和资源的应用。
    • 特性
      • 设置android:sharedUserId="android.uid.shared"后,应用会以同一个用户ID运行,从而能够互相访问彼此的数据目录。
      • shared签名的应用一般不涉及最底层的系统服务,而是针对系统内部具有一定协作关系的服务或者组件提供数据共享能力。
  4. 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.制作

主要利用keytoolopenssl,将系统的platform.pk8platform.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: [email protected], CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US
Issuer: [email protected], 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                                         ...
]
[[email protected], 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,下期再见!

参考资料:

  1. source.android.google.cn/docs/core/o...
  2. learn.microsoft.com/zh-cn/xamar...
  3. github.com/getfatday/k...
相关推荐
练习本2 小时前
Android系统架构模式分析
android·java·架构·系统架构
每次的天空7 小时前
Kotlin 内联函数深度解析:从源码到实践优化
android·开发语言·kotlin
练习本7 小时前
Android MVC架构的现代化改造:构建清晰单向数据流
android·架构·mvc
早上好啊! 树哥8 小时前
android studio开发:设置屏幕朝向为竖屏,强制应用的包体始终以竖屏(纵向)展示
android·ide·android studio
YY_pdd8 小时前
使用go开发安卓程序
android·golang
Android 小码峰啊10 小时前
Android Compose 框架物理动画之捕捉动画深入剖析(29)
android·spring
bubiyoushang88810 小时前
深入探索Laravel框架中的Blade模板引擎
android·android studio·laravel
cyy29810 小时前
android 记录应用内存
android·linux·运维
CYRUS STUDIO11 小时前
adb 实用命令汇总
android·adb·命令模式·工具
这儿有一堆花11 小时前
安卓应用卡顿、性能低下的背后原因
android·安卓