普通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进行签名
相关推荐
Estar.Lee10 分钟前
时间操作[计算时间差]免费API接口教程
android·网络·后端·网络协议·tcp/ip
找藉口是失败者的习惯1 小时前
从传统到未来:Android XML布局 与 Jetpack Compose的全面对比
android·xml
Jinkey2 小时前
FlutterBasic - GetBuilder、Obx、GetX<Controller>、GetxController 有啥区别
android·flutter·ios
大白要努力!4 小时前
Android opencv使用Core.hconcat 进行图像拼接
android·opencv
天空中的野鸟5 小时前
Android音频采集
android·音视频
小白也想学C6 小时前
Android 功耗分析(底层篇)
android·功耗
曙曙学编程6 小时前
初级数据结构——树
android·java·数据结构
闲暇部落8 小时前
‌Kotlin中的?.和!!主要区别
android·开发语言·kotlin
诸神黄昏EX10 小时前
Android 分区相关介绍
android
大白要努力!11 小时前
android 使用SQLiteOpenHelper 如何优化数据库的性能
android·数据库·oracle