参考资料:
https://www.cnblogs.com/onelikeone/p/10920629.html
https://www.cnblogs.com/xiaoshen666/p/11008255.html
今天在外网上下载了一个apk,想安装到我的Huawei Mate20X 上,没想到出现了这一幕:
提示我这个apk没有包含任何证书?什么鬼,没有证书这个apk是怎么发布的,在网上查找了资料,发现大部分都是在扯淡完全不解决问题。经过20多分钟的折腾,我成功地使用了重签名的方式解决了这个问题,这篇文章将是一个半教程的形式,需要读者有一定的开发经验和安全协议知识。
1. 首先明确问题,这个apk的证书出现了问题
由于Android系统的安全规范,apk必须进行签名才能够发布,如果系统验证后发现签名不一致,说明这个apk被篡改了。如果系统发现完全没有签名,那么它会直接拒绝签名。找到问题后我们的解决方案应该完全围绕签名来走。
2. 看看这个apk的签名出现了什么问题
上Java程设课安装过jdk,直接运行keytools命令检查一下apk的签名状态。(这里我把apk重命名成了myapp.apk)
运行如下命令:
keytool -printcert -jarfile 你的apk文件
看不出毛病啊,这不是有签名吗?只不过签名的信息看起来比较少。看来并不是没有签名,而是这个签名华为不认啊。
3. 着手对apk进行重签名
我们使用解压缩软件打开myapp.apk,里面有一个META-INF文件夹,这里面就是apk数字签名的存放位置。我们将它删掉,使用压缩软件把这里面的东西重新压缩成.zip文件,并重命名为usigned.apk。
这样我们就有了一个未被签名的usigned.apk文件。
4. 正式生成RSA签名证书
签名就需要公私钥了,正规发布的话可能就要用到CA了,但是我们不用这么麻烦,直接自签发证书就好了。运行如下命令:
keytool -genkey -v -keystore myApp.keystore -alias myApp.keystore -keyalg RSA -validity 30000
它会问你几个信息,你的名字啊,国家啊,机构啊啥啥的。直接瞎填就好了,不过要记住你的密码。运行完获得了一个文件myApp.keystore,如果我没猜错的话这个就相当于给你弄了个私钥证书了,不过是自签发的。
然后我们将myApp.keystore和usigned.apk放到同一个文件夹下,运行如下命令:
jarsigner -verbose -keystore myApp.keystore -signedjar sign.apk usigned.apk myApp.keystore
这段代码就是使用jarsigner这个签名软件对usigned.apk进行签名,生成签名后的apk。依据的RSA签名证书就是自签发的myApp.keystore。
这样我们就签好名啦,放到手机上安装一下:
安装正常且能正常打开~~ 一切正常。
总结:因为华为严格的安全特性,导致有些apk签名无法被识别,这时候我们可以用 keytools + jarsigner 进行重签名。如果对这方面的操作不熟悉,是否可以考虑在线生成证书?如果在线生成证书不好使,是否可以考虑将其他apk的证书直接copy过去重打包?(因为经常会报错签名不一致,但还是让我们安装了)。我没有进行尝试,感兴趣的朋友可以试一试。
补充:另外看到有网友提到一个叫MT管理器的安卓app可以更方便地管理apk签名,读者可以一试。