1. Android签名机制及原理
Android系统在安装APK的时候,首先会检验APK的签名,如果发现签名文件不存在或者校验签名失败,则会拒绝安装,所以应用程序在发布之前一定要进行签名。给APK签名可以带来以下好处:
- 应用程序升级:若包名相同而签名不同,系统会拒绝安装新版应用。
- 应用程序模块化:系统允许同一个证书签名的多个应用程序在一个进程里运行,系统实际把他们作为一个单个的应用程序。此时就可以把我们的应用程序以模块的方式进行部署,而用户可以独立的升级其中一个模块。
- 代码或数据共享:一个应用程序可以为另一个以相同证书签名的应用程序公开自己的功能与数据。
- 应用程序的可认定性:签名信息中包含有开发者信息,在一定程度上可以防止应用被伪造。
对一个APK文件签名之后,APK文件根目录下会增加META-INF目录,该目录下增加三个文件:
MANIFEST.MF NETEASE.RSA NETEASE.SF |
其中.RSA文件还可能是.DSA文件,RSA与SF文件的文件名可以更改,但是它们的命名必须一样。
1) MANIFEST.MF中保存了APK里所有文件的SHA1校验值的BASE64编码。
2) SF里保存了MANIFEST.MF文件的SHA1校验值的BASE64编码,同时还保存了MANIFEST.MF中每一条记录的SHA1检验值的BASE64编码。
3) RSA则包含了签名的公钥和所有者等信息,还保存了用SHA1withRSA签名算法对SF文件的签名结果信息。
Android系统就是根据这三个文件的内容对APK文件进行签名检验的。
2. Android 签名方法
1) apksign、jarsinger
一般的签名过程可以由apksign.jar或者jarsinger.jar完成。
apksign.jar由Android SDK提供,使用方法如下:
java -jar signapk.jar testkey.x509.pem testkey.pk8 update.apk update_signed.apk |
它接受一个PEM公钥文件,PK8私钥文件,对update.apk进行签名,签名后的文件保存到update_signed.apk。
jarsinger是由JDK提供,使用方法如下:
jarsigner -verbose -keystore d:\\debug.keystore -signedjar update_signed.apk update.apk androiddebugkey -digestalg SHA1 -sigalg MD5withRSA -keypass android -storepass android |
经过测试,发现以上两个传统的签名工具存在以下缺点:
A. jarsigner在对一个已经有META-INF目录的APK进行签名的时候,有可能会报错:
jarsigner: 无法对 jar 进行签名: java.util.zip.ZipException: invalid entry compressed size (expected 1368 but got 1379 bytes) |
B. 如果APK中已经有签名文件且签名文件中的RSA(或DSA)、SF文件的命名不是CERT的时候,用这两个签名工具进行签名后,会出现:META-INF目录下会有两个RSA/SF文件,会导致APK在安装的时候失败。
C. 签名花费时间长。这两个签名工具在生成签名后的APK时,是按Zip中一个entry接一个entry 依次拷贝的,效率低。因为游戏类型APK类文件数量一般比较多,所以这一缺陷在签名游戏类型APK时,体现得尤为明显。
2) 极速签名工具(ApkSinger)
极速签名工具克服了signapk.jar与jarsigner在签名过程的缺点,使用方法:
java -jar ApkSigner.jar [-appname test] -keystore keystorePath -alias alias [-pswd password] [-aliaspswd aliasPassword] apkPath(or directory) |
- -appname 待签名的应用程序名,可选,但建议不同的APP填上对应的app名
- -keystore 后跟.keystore签名文件
- -alias 后跟签名别名
- -pswd 后跟对应签名的密码,可选,如果不填,则签名的时候需要手动输入
- -aliaspswd 对应别名alias的密码,如果没有则默认使用keystore Password
最后跟待签名的APK路径或者目录路径 ,如果跟的是目录则是批量签名.
【附】 描述下Android数字签名。
- 所有的应用程序都必须有数字证书,Android系统不会安装一个没有数字证书的应用程序
- Android程序包使用的数字证书可以是自签名的,不需要一个权威的数字证书机构签名认证
- 如果要正式发布一个Android ,必须使用一个合适的私钥生成的数字证书来给程序签名,而不能使用adt插件或者ant工具生成的调试证书来发布。
- 数字证书都是有有效期的,Android只是在应用程序安装的时候才会检查证书的有效期。如果程序已经安装在系统中,即使证书过期也不会影响程序的正常功能。