Android系统禁止更新安装签名不一致的APK 如果应用需要使用system权限,必须保证APK签名与Framework签名一致
源码签名:
1.找到系统签名文件 文件路径:在源码的\build\target\product\security目录下有platform.x509pem和platform.pk8两个文件



使用:
java -jar signapk.jar platform.x509.pem platform.pk8 in.apk(预签名的apk) out.apk(签名之后的apk)
java -jar signapk.jar testkey.x509.pem testkey.pk8 源.apk 目标.apk
这条命令的意义是:通过signapk.jar这个可执行jar包,以“testkey.x509.pem”这个证书文件和“testkey.pk8”这个私钥文件对“源.apk”进行签名,签名后的文件保存为“目标.apk”
signapk.jar做了什么
signapk.jar是Android源码包中的一个签名工具

1、 Android签名机制其实是对APK包完整性和发布机构唯一性的一种校验机制。 2、 Android签名机制不能阻止APK包被修改,但修改后的再签名无法与原先的签名保持一致。(拥有私钥的情况除外)。 3、 APK包加密的公钥就打包在APK包内,且不同的私钥对应不同的公钥。换句话言之,不同的私钥签名的APK公钥也必不相同。所以可以根据公钥的对比,来判断私钥是否一致。
签名好的APK包中会多一个叫做META-INF的文件夹。里面有三个文件,分别名为MANIFEST.MF、CERT.SF和CERT.RSA。signapk.jar就是生成了这几个文件(其他文件没有任何改变。因此我们可以很容易去掉原有签名信息)。
- MANIFEST.MF
程序遍历apk包中的所有文件(entry),对非文件夹非签名文件的文件(图片、资源xml、so、.dex) 逐个生成SHA1的数字签名信息,再用Base64进行编码
之后将生成的签名写入MANIFEST.MF文件

介绍下SHA1数字签名。简单地说,它就是一种安全哈希算法,类似于MD5算法。它把任意长度的输入,通过散列算法变成固定长度的输出(这 里我们称作“摘要信息”)。
不能仅通过这个摘要信息复原原来的信息。另外,它保证不同信息的摘要信息彼此不同。
因此,如果你改变了apk包中的文件,那 么在apk安装校验时,改变后的文件摘要信息与MANIFEST.MF的检验信息不同,于是程序就不能成功安装
- CERT.SF
对前一步生成的Manifest,使用SHA1-RSA算法,用私钥进行签名
RSA是一种非对称加密算法。用私钥通过RSA算法对摘要信息进行加密。在安装时只能使用公钥才能解密它。解密之后,将它与未加密的摘要信息进行对比,如果相符,则表明内容没有被异常修改。
- CERT.RSA
生成MANIFEST.MF没有使用密钥信息,生成CERT.SF文件使用了私钥文件。那么我们可以很容易猜测到,CERT.RSA文件的生成肯定和公钥相关。 CERT.RSA文件中保存了公钥、所采用的加密算法等信息
生成Framework签名一致的keystore
将.x509.pem 和.pk8导入keystore文件、或者**.jks文件** 需要openssl工具 、密钥和证书管理工具keytool ,并配置好环境变量
keytool工具 | |
---|---|
参数 | 解释 |
-certreq | 生成证书请求 |
-changealias | 更改条目的别名 |
-delete | 删除条目 |
-exportcert | 导出证书 |
-genkeypair | 生成密钥对 |
-genseckey | 生成密钥 |
-gencert | 根据证书请求生成证书 |
-importcert | 导入证书或证书链 |
-importpass | 导入口令 |
-importkeystore | 从其他密钥库导入一个或所有条目 |
-keypasswd | 更改条目的密钥口令 |
-list | 列出密钥库中的条目 |
-printcert | 打印证书内容 |
-printcertreq | 打印证书请求的内容 |
-printcrl | 打印 CRL 文件的内容 |
-storepasswd | 更改密钥库的存储口令 |
脚本生成
附件为脚本、framework签名证书和私钥文件 ,是从Android源码拷贝,用时需要替换自己平台的
- 修改脚本

- 运行脚本生成
./platform-to-keystore
脚本权限需要修改成可执行权限
- 使用
将生成的签名文件放置AS使用

Android源码证书和私钥
以上都是system app开发这要掌握的 如果我从0开始做系统呢?如何生成自己系统的**.x509.pem** 、**.pk8
证书和私钥
每个密钥都包含两个文件:一个是扩展名为 .x509.pem 的证书,另一个是扩展名为 .pk8 的私钥。私钥需要加以保密,并用于对 apk 包进行签名。密钥本身也可能受密码保护。相比之下,证书只包含公开的一半密钥,因此可以大范围地分发。证书被用于验证某个 apk 包是否由相应的私钥进行签名。
标准 Android 版本使用四个密钥,所有这些密钥都位于 build/target/product/security
中:
- testkey(testkey.pk8)
适用于未另外指定密钥的 apk 包的通用默认密钥。
- 平台(platform.pk8)
适用于核心平台所包含的 apk 包的测试密钥。
- 共享(shared.pk8)
适用于家庭/联系人进程中的共享内容的测试密钥。
- 媒体(media.pk8)
适用于媒体/下载系统所包含的 apk 包的测试密钥
单个 apk 包通过在其 Android.mk 文件中设置 LOCAL_CERTIFICATE 来指定其中一个密钥。(如果未设置此变量,则使用 testkey。)
自动生成密钥
Android 树的 build/target/product/security
目录中提供了测试密钥。使用 make
编译 Android 操作系统映像便可使用这些测试密钥对所有 .apk
文件进行签名。由于这些测试密钥是公开的,任何人都可以使用相同的密钥对他们自己的 .apk 文件签名,这样他们就能够替换或盗用您的操作系统映像中编译的系统应用。因此,必须使用只有自己才能访问的特殊“发布密钥”集对公开发布或部署的 Android 操作系统映像进行签名。
要生成自己的唯一发布密钥集,请在 Android 树的根目录下运行以下命令:
subject='/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/emailAddress=android@android.com'
mkdir ~/.android-certs
for x in releasekey platform shared media; do \
./development/tools/make_key ~/.android-certs/$x "$subject"; \
done
//输入自己的密码 我输入的:123456

手动生成密钥
Android 使用公开指数为 3 的 2048 位 RSA 密钥。您可以使用 openssl.org 提供的 openssl 工具来生成证书/私钥对:
- generate RSA key
openssl genrsa -3 -out chrisli.pem 2048

- create a certificate with the public part of the key
openssl req -new -x509 -key chrisli.pem -out chrisli.x509.pem -days 1000000 -subj '/C=US/ST=California/L=San Narciso/O=chrisli, Inc./OU=chrisli Mobility/CN=chrisli/emailAddress=chrisli@example.com'
- create a PKCS#8-formatted version of the private key
openssl pkcs8 -in chrisli.pem -topk8 -outform DER -out chrisli.pk8 -nocrypt
上述 openssl pkcs8 命令可创建一个适用于该版本系统的 .pk8 文件,该文件未设置密码。要创建一个带有密码保护的 .pk8 文件(应当为所有实际的发布密钥执行此步骤),请将 -nocrypt
参数替换为 -passout stdin
;这样 openssl 将使用从标准输入中读取的密码来加密私钥。该过程中不会输出任何提示。因此,当系统确实只是在等待您输入密码时,如果 stdin 是终端,程序将会处于挂起状态。可以对 Passout 参数使用其他值,以便从其他位置读取密码
openssl pkcs8 -in chrisli.pem -topk8 -outform DER -out chrisli.pk8 -passout stdin

- **最后删除临时文件chrisli.pem **
chrisli.pem 中间文件包含不受任何类型的密码保护的私钥,因此在生成发布密钥时应谨慎处理该文件
shred --remove chrisli.pem

jarsigner、keytool工具
jarsigner -verbose -keystore demo.keystore -signedjar test_signed.apk test.apk mykey
# test_signed.apk是签名之后的文件
# test.apk是需要签名的文件
另外需要注意的是,如果你的jdk版本在1.7以上,你在对apk签名时,需要加上这个参数:
-digestalg SHA1 -sigalg MD5withRSA |
---|
否则同样会出现:Failure [INSTALL_PARSE_FAILED_NO_CERTIFICATES]的错误。
jarsigner -verbose -keystore platform.keystore -signedjar xlog.apk xlogging-sample-debug.apk spacebridge -digestalg SHA1 -sigalg MD5withRSA
几种常用命令
1、查看keystore的信息
keytool -list -keystore demo.keystore -alias mykey -v

2、查看keystore的公钥证书信息
keytool -list -keystore demo.keystore -alias mykey -rfc

(注:获取Base64格式的公钥证书,RFC 1421) 3、查看apk的签名信息
jarsigner -verify -verbose -certs <your_apk_path.apk>
apk安装签名解析
Android系统安装程序肯定会获取APK信息进行比对,所以]可以通过Android源码获得一些思路和帮助。 apk安装是PackageParser负责解析安装包
PackageParser负责AndroidManifest(applicationInfo、Version、mSharedUserId、permissions、四大组件等)、签名读取解析

PackageParser 源码路径:
/frameworks/base/core/java/android/content/pm
三方app开发签名
三方开发就是普通的app开发不需要系统签名,开发出来的app运行在各个厂商的Android系统上,没有特殊要求,直接使用AS生成