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/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的解释,参照文档

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

  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: 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,下期再见!

参考资料:

  1. source.android.google.cn/docs/core/o...
  2. learn.microsoft.com/zh-cn/xamar...
  3. github.com/getfatday/k...
相关推荐
吃着火锅x唱着歌26 分钟前
PHP7内核剖析 学习笔记 第四章 内存管理(1)
android·笔记·学习
_Shirley2 小时前
鸿蒙设置app更新跳转华为市场
android·华为·kotlin·harmonyos·鸿蒙
hedalei4 小时前
RK3576 Android14编译OTA包提示java.lang.UnsupportedClassVersionError问题
android·android14·rk3576
锋风Fengfeng4 小时前
安卓多渠道apk配置不同签名
android
枫_feng4 小时前
AOSP开发环境配置
android·安卓
叶羽西4 小时前
Android Studio打开一个外部的Android app程序
android·ide·android studio
qq_171538856 小时前
利用Spring Cloud Gateway Predicate优化微服务路由策略
android·javascript·微服务
Vincent(朱志强)7 小时前
设计模式详解(十二):单例模式——Singleton
android·单例模式·设计模式
mmsx8 小时前
android 登录界面编写
android·登录界面
姜毛毛-JYM8 小时前
【JetPack】Navigation知识点总结
android