一、Android 签名机制Android 签名机制可划分为 ROM 签名机制与第三方 APK 签名机制,在这里只讨论 APK 签名机制。 Android 系统在安装 APK 的时候,首先会检验 APK 的签名,如果发现签名文件不存在或者校验签名失败,则会拒绝安装,所以应用程序在发布之前一定要进行签名。给 APK 签名可以带来以下好处:
二、签名原理对一个 APK 文件签名之后,APK 文件根目录下会增加 META-INF 目录,该目录下增加三个文件: 其中 .RSA 文件还可能是 .DSA 文件,RSA 与 SF 文件的文件名可以更改,但是它们的命名必须一样。 MANIFEST.MF 中保存了 APK 里所有文件的 SHA1 校验值的 BASE64 编码,格式如下(一个文件对应一条记录):
Name: res/anim/abc_fade_in.xml
SHA1-Digest: ohPEA4mboaFUu9LZMUwk7FmjbPI= SF 文件里保存了 MANIFEST.MF 文件的 SHA1 校验值的 BASE64 编码,同时还保存了 MANIFEST.MF 中每一条记录的 SHA1 检验值 BASE64 编码,格式如下:
SHA1-Digest-Manifest: ZRhh1HuaoEKMn6o21W1as0sMlaU= RSA 文件则包含了签名的公钥、签名所有者等信息,还保存了用 SHA1withRSA 签名算法对SF文件的签名结果信息。 Android 系统就是根据这三个文件的内容对 APK 文件进行签名检验的。 三、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 其中: -keystore 表示 keystore 文件的路径
androiddebugkey 表示 keystore 中的一个别名
-digestalg 表示摘要算法
-sigalg 表示签名算法
-keypass 表示别名密码
-storepass 表示 keystore 密码 经过测试,我们发现以上两个传统的签名工具存在以下缺点: 1)、jarsigner 在对一个已经有 META-INF 目录的 APK 进行签名的时候,有可能会报错:
jarsigner: 无法对 jar 进行签名: java.util.zip.ZipException: invalid entry compressed size (expected 1368 but got 1379 bytes)
2)、如果 APK 中已经有签名文件且签名文件中的 RSA(或 DSA )、SF 文件的命名不是 CERT 的时候,用这两个签名工具进行签名后,会出现: META-INF 目录下会有两个 RSA / SF文件,会导致 APK 在安装的时候失败。 3)、签名花费时间长。这两个签名工具在生成签名后的 APK 时,是按 Zip 中一个 entry 接一个 entry 依次拷贝的,效率十分低。因为游戏类型 APK 类文件数量一般比较多,所以这一缺陷在签名游戏类型 APK 时,体现得尤为明显。 2、极速签名工具(ApkSinger)针对 signapk.jar 与 jarsigner 在签名过程的缺点,我们开发了新的签名工具 ApkSinger.jar。主要是在保证签名正确的基础上: 1) 可以对已签名 APK 或已存在 META-INF 目录的 APK 进行签名。 2) 增加对目录处理的支持。通常在打多个渠道包时,需要对多个 APK 进行签名,所以增加对目录的签名支持是有必要的。 3) 提高处理效率,优化签名时间。对目录处理时,优势犹为明显! 命令行下运行:java -jar ApkSigner.jar 查看版本号与使用方法:
NetEase ApkSigner1.2
Usage:
java -jar ApkSigner.jar [-appname test] -keystore keystorePath -alias alias [-pswd password] [-aliaspswd aliasPassword] apkPath(or directory)
选了几个不同体积的APK包进行测试,分别是:20M,144M,343M。分别建立文件夹 A、B、C, 分别放5个包(假设要打5个渠道包)。分别调用 jarsigner,signapk.jar, ApkSinger.jar 对各个文件夹里的APK进行签名,签名速度结果对比如下: 可以看出,极速签名工具(ApkSinger)的速度较其他的签名工具是非常快的,可以极大地优化打包流程,节省打包时间。工具下载链接:http://apk.aq.163.com/apkpack.do#download,另外,网易云加密 中也内置了快速签名工具以及多渠道打包的功能,欢迎提出反馈和建议。 APP架构师 |
|