这几天通过查资料、看源码和做试验,对android签名系统有了大概的理解,现总结一下,供参考:
关于签名的作用
APK
签名的作用:
1 发送者的身份认证,由于开发商可能通过使用相同的Package Name来混淆替换已经安装的程序,以此保证签名不同的包不被替换。
2
保证信息传输的完整性,签名对于包中的每个文件进行处理,以此确保包中内容不被替换,防止交易中的抵赖发生,Market
对软件的要求。
Recovery
签名作用:
Recovery
进行签名的主要作用是用来验证数据的完整性。
如何签名
Android使用SHA1-RSA算法进行签名。可通过eclipse插件进行,可以通过keytool和jarsigner 用命令行执行。也可以在源码下进行签名。以源码下签名方法来介绍:
生成密钥对方法:
Android源码目录development\tools 下有make_key脚本:
生成公钥:openssl genrsa -3 -outtestkey.pem 2048
转换成X509证书格式:
openssl req -new -x509 -key testkey.pem -out testkey.x509.pem -days 10000-subj ‘xx’
生成私钥:
openssl pkcs8 -in testkey.pem-topk8 -outform DER -out testkey.pk8 –nocrypt
具体参数可以在网上查看。目前我们使用默认的
testkey
密钥对。
对
APK
签名命令:
signapk publickey.x509[.pem]privatekey.pk8 input.apk output.apk
对recovery 签名命令:
signapk –w publickey.x509[.pem]privatekey.pk8 input.zip output.zip
- w参数表示对整个文件进行签名,目前看只是在制作recovery升级包时使用。
签名后,输出文件的meta_inf目录下生长如下文件:
MANIFEST.MF
:对非文件夹非签名文件的文件,逐个生成
SHA1
的数字签名信息
CERT.SF
:对
Manifest
文件,使用
SHA1-RSA
算法,用私钥进行签名。
CERT.RSA
:
CERT.RSA
文件中保存了公钥、所采用的加密算法等信息。
APK
验证:
安装
apk
时,通过
CERT.RSA
查找公钥和算法,并对
CERT.SF
进行解密和签名验证,确认
MANIFEST.MF
,最终对每个文件签名校验。
升级时,
android
也会进行签名验证。如果遇到以下情况,都不能完成升级:
1) 两个应用,名字相同,签名不同
2) 升级时前一版本签名,后一版本没签名。
3) 升级时前一版本为DEBUG签名,后一个为自定义签名。
4) 升级时前一版本为Android源码中的签名,后一个为DEBUG签名或自定义签名。
5) 安装未签名的程序。
6) 安装升级已过有效期的程序。
以上可以看到,随便更换密钥对后签名生成的
apk
也是可以安装在任何平台的。因为公钥是放在
apk
里的。
RECOVERY
:
Recovery公钥是固定在代码里面。并没有采用CERT.RSA里面公钥。目前几乎所有的手机平台都是用testkey。固定公钥目的可能是为了确保其它平台的升级包不能被升级。比如我们统一更换了一个密钥对,那么recovery里面固定的公钥更改后,用testkey做成的升级包是无法升级成功的。
同时
recovery只是对整个升级压缩文件进行签名校验(前面说过recovery签名使用的是-w)。
Recovery 代码里面使用的公钥是按照rsapublickey 数据结构存储。这个数据是通过dumppublickey工具从制作出来的x509证书文件中获得。Dumppublickey代码在网上可以查找到。