最近在着手对一批APK提取证书信息,却遇到了Bug。
正常情况下,我们借助Java自带的keytool工具,执行keytool -printcert -jarfile a.apk,就可以获得如下图所示的证书信息

但是在对几百个APK进行批量操作的时候,发现有少数APK,执行上述命令时会提示"不是已签名的 jar 文件"

如果只是想解决这个问题倒是简单,只需要把apk包中META-INF/*.RSA文件解压出来,再调用keytool -printcert -file CERT.RSA即可(对于正常的APK,这两个命令获得的结果相同)

由于用了apktool反编译,因此多了层original目录
但是我还希望进一步探究其原因,由于keytool的源码网上找不到,因此只能另辟蹊径。
通过搜索,用于apk证书信息提取的工具,Java除了提供了keytool之外,还提供了一个叫做jarsigner的工具。接下来,
1)当尝试对每一个keytool无法解析的apk,调用jarsigner -verify *.apk时,结果中均有这么一句
“由于该 jar 是使用目前已禁用的弱算法签名的, 因此该 jar 将被视为未签名。”

2)当尝试对keytool能正常提取信息的apk,调用上述命令时,结果中均无此提示。
因此,我最终的猜测是:Keytool一旦检测到弱算法签名,就会提示说 "不是已签名的 jar 文件"。
目前只能分析到这了,而且还有一个未解之谜:为何keytool -printcert -file a.RSA的结果与jarsigner -certs -verify a.apk的结果中的签名算法可能不同?
本文如有错误,欢迎大家指正~