文章目录

这几天遇到一件怪事,使用加固工具后,打包出来的APK无法在Android 4.2版本的手机上安装,不使用加固打出来的安装包却可以安装。于是找加固厂商询问原因,加固厂商拿了不能安装的文件后,又发了一个安装包让我们测试一下,结果可以了。询问原因,说是我们给的安装包没有签名,加上签名信息就好了。于是用keytool工具看了下原安装文件的签名信息,发现都有。把执行命令包含有签名信息的截图发过去了之后,加固厂商问了使用的签名工具,然后说是用jarsigner工具的问题。于是一查,还真是。

原来默认打包使用的是gradlew assembleRelease命令,使用这个命令默认使用的是Android SDK中的apksigner命令读取gradle文件中的签名信息进行签名。这就解释了为什么没有加固的安装包可以正常安装。

因为加固后,需要重新签名,这时自动打包在jenkins上使用的是jarsigner命令进行签名。而这个工具是由jdk提供的,而且不同的jdk版本的算法不一致。在jdk7版本开始使用SHA256,而4.2系统版本只支持SHA1,所以导致无法安装。

解决办法是执行jarsigner命令时,使用参数,命令如下所示:

1
jarsigner -keystore debug.keystore -digestalg SHA1 -sigalg SHA1widthRSA -signedjar test_signed.apk test_unsigned.apk

即要加上-digestalg SHA1 -sigalg SHA1widthRSA参数即可。

但是上述方法不推荐,因为在Android 7.0版本以上会使用V2签名,v1签名会有Janus安全漏洞,所以签名apk文件时还是得使用apkSigner比较好。

命令如下所示:

1
java -jar apksigner.jar sign --v1-signing-enabled true --v2-signing-enabled true --ks D:\test.jks --ks-pass pass:storePassword --ks-key-alias keyAlias --key-pass pass:keyPassword --in unsigned.apk --out signed.apk

apksigner.jar文件是在Android SDK的build-tool目录中相应版本目录中的lib目录下。注意这两个参数--v1-signing-enabled true --v2-signing-enabled true是可选,如果不加这两个参数,其默认值为true,这样可以在android 7.0版本以上避免Janus安全漏洞。另外还要注意密钥之前要加上pass:前缀。

查看apk签名信息的命令如下所示:

1
java -jar apksigner.jar verify -v --print-certs 1.apk

查看签名文件中的签名信息的命令如下所示:

1
keytool -list -v -keystore D:\test.jks

输入密钥库口令后即可输出签名信息。

文章目录