普通Android应用的系统签名

一、前言

对于常见的Android开发来说,普通级别的app已经满足不了需求。对系统的要求能力越来越定制化,所以针对系统权限的需求也迫在眉睫。 那怎么通过aosp的系统签名,将普通app升级为系统权限的app,使app能访问系统资源的权限呢?

二、流程

1. 手动签名apk文件

a. app设置系统权限

在app项目的AndroidManifest文件的节点新增

xml 复制代码
<manifest
	xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:sharedUserId="android.uid.system">

b. 编译打包apk

生成对应apk

c. 准备签名文件及工具

需要准备:

  • java环境命令

  • 系统签名文件:platform.pk8、platform.x509.pem

  • signapk.jar:

    • 进入/build/tools/signapk/文件夹
    • 执行命令: mm
    • 在out/host/linux-x86/framework/目录找到signapk.jar

d. 签名打包好的apk

tips: 最好将工具等文件复制到统一文件中,比较好操作,中途会遇到各式各样的问题,操作篇尾

bash 复制代码
java -jar signapk.jar platform.x509.pem platform.pk8 app-debug.apk new.apk 

e. 安装新包测试

卸载旧包,安装新包,即可完成系统权限

2. 自动签名apk文件

每次开发时,总是要手动签名新打出的安装包,很不方便,直接在打包时完成系统签名更高效

a. pk8 私钥解密pem格式

此时会生成platform.priv.pem文件

  • platform.priv.pem为生成文件名称
bash 复制代码
openssl pkcs8 -in platform.pk8 -inform DER --outform PEM -out platform.priv.pem -nocrypt

b. 私钥通过公钥pem加密pk12

此时会生成platform.pk12文件

  • platform.priv.pem为上一步生成的文件
  • zxxkey为AliasName
bash 复制代码
openssl pkcs12 -export -in platform.x509.pem -inkey platform.priv.pem -out platform.pk12 -name zxxkey

需要输入两次密码:(实测store和key密码需要一致)

c. 通过java的keytool 工具生成 keystore

  • 12345678为store密码
  • zxxkey为上一步设置的别名,需要与上面保持一致

jks:

bash 复制代码
keytool -importkeystore -destkeystore platform.jks -srckeystore platform.pk12 -srcstoretype PKCS12 -srcstorepass 12345678 -alias zxxkey

keystore:

bash 复制代码
keytool -importkeystore -destkeystore platform.keystore -srckeystore platform.pk12 -srcstoretype PKCS12 -srcstorepass 12345678 -alias zxxkey

d. 项目中使用签名

1)引入签名文件:

将keystore或者jks文件引入项目

2)创建keystore.properties:

properties 复制代码
keyAlias=zxxkey
keyPassword=12345678
storeFile=../key/platform.jks
storePassword=12345678

3)在app/build.gradle.kts引入signConfig:

kotlin 复制代码
import java.io.FileInputStream
import java.util.Properties

...

val keystorePropertiesFile = rootProject.file("keystore.properties")
val keystoreProperties = Properties()
keystoreProperties.load(FileInputStream(keystorePropertiesFile))

...

android {
    
    ...
    
     signingConfigs {
        create("release") {
            keyAlias = keystoreProperties.getProperty("keyAlias")
            keyPassword = keystoreProperties.getProperty("keyPassword")
            storeFile = file(keystoreProperties.getProperty("storeFile"))
            storePassword = keystoreProperties.getProperty("storePassword")
        }
    }

    buildTypes {
        debug {
            signingConfig = signingConfigs.getByName("release")
        }
        release {
            signingConfig = signingConfigs.getByName("release")
            isMinifyEnabled = false
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"
            )
        }
    }
    
    ...
}

三、问题

1. java版本问题

Q:版本异常?

cmd 复制代码
Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.UnsupportedClassVersionError: com/android/signapk/SignApk has been compiled by a more recent version of the Java Runtime (class file version 53.0), this version of the Java Runtime only recognizes class file versions up to 52.0

A:解决方案:

升级jdk版本,52.0版本为java8,选用更高版本即可。

/home/zengxiangxi/Developer/JDK/jdk-9.0.4/bin/java

bash 复制代码
/home/zengxiangxi/Developer/JDK/jdk-9.0.4/bin/java -jar signapk.jar platform.x509.pem platform.pk8 app-debug.apk new.apk 

2. 签名问题报错

Q:找不到依赖库?

cmd 复制代码
Exception in thread "main" java.lang.UnsatisfiedLinkError: no conscrypt_openjdk_jni-linux-x86_64 in java.library.path
	at java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2541)
	at java.base/java.lang.Runtime.loadLibrary0(Runtime.java:873)
	at java.base/java.lang.System.loadLibrary(System.java:1857)
	at org.conscrypt.NativeLibraryUtil.loadLibrary(NativeLibraryUtil.java:54)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

A:附带以来库路径。

-Djava.library.path="/home/zengxiangxi/Project/aosp/out/soong/host/linux-x86/lib64"

stackoverflow.com/questions/4...

bash 复制代码
~/Developer/JDK/jdk-9.0.4/bin/java -Djava.library.path="/home/zengxiangxi/Project/aosp/out/soong/host/linux-x86/lib64" -jar signapk.jar platform.x509.pem platform.pk8 app-debug.apk new.apk

四、文档链接

  1. Android签名:pem和pk8转化为keystore,jks
  2. 用SignApk.jar对APK进行签名
相关推荐
千里马学框架1 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台1 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone1 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc1 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo2 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077002 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼2 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone2 天前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen2 天前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone2 天前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui