本文为转载文章, 仅用于自己的知识管理收集, 如果涉及侵权,请联系 suziwen1@gmail.com,会第一时间删除
收集该文章,并非代表本人支持文中观点,只是觉得文章内容容易引起思考,讨论,有它自有的价值
【一、前言】
我们自己开发的app签名,就代表着我自己的版权,以后要进行升级,也必须要使用相同的签名才行。签名就代表着自己的身份即keystore。小编所在项目,遇到应用被恶意篡改的情况。新版本客户端加入了在线签名逻辑以及防止二次签名逻辑。小编对相关知识加深了理解,并运用在项目测试中,分享给大家。
【二、Android应用签名和签名方式】
1、APK文件结构与应用签名
Android应用是用Java编写的,利用Android SDK编译代码,并且把所有的数据和资源文件打包成一个APK (Android Package)文件,这是一个后缀名为.apk的压缩文件,APK文件中包含了一个Android应用程序的所有内容,是Android平台用于安装应用程序的文件。APK就是一个zip压缩包,解开这个APK包我们可以看到以下的结构:
META-INF目录:保存应用的签名信息,签名信息可以验证APK文件的完整性。Android SDK在打包APK时会计算APK包中所有文件的完整性,并且把这些完整性保存到META-INF文件夹下,应用程序在安装的时候首先会根据META-INF文件夹校验APK的完整性,这样就可以保证APK中的每一个文件都不能被篡改。以此来确保APK应用程序不被恶意修改或者病毒感染,有利于确保Android应用的完整性和系统的安全性。META-INF目录下包含的文件有CERT.RSA,CERT.DSA,CERT.SF和MANIFEST.MF,其中CERT.RSA是开发者利用私钥对APK进行签名的签名文件,CERT.SF,MANIFEST.MF记录了文件中文件的SHA-1哈希值。
2、apk的签名方式
(1). 通过ADT提供的图形化界面完成apk签名;即用AS来完成
(2). 通过在build.gradle配置再通过命令行完成apk签名
方式一:通过AndroidStudio进行签名
Keystore路径,可以选择已有,也可以新创建。
创建数字证书
指定签名后的APK安装包的存储路径
注意:
在上面的截图中,我们可以看到Signature Versions有两个选项,V1 (jar Signature)、V2 (Full APK Signature)。
二者的区别:
V1:jar Signature来自JDK,可对签名后的文件,作适当修改,并重新压缩。
V2:Android 7.0引入一项新的应用签名方案,不能对签名后的APK作任何修改,包括重新解压。因为它是针对字节进行的签名,所以任何改动都会影响最终结果。
Signature Versions不能只选择 V2(Full APK Signature),应该选择V1(Jar Signature),或者选择V1和V2。只勾选V2就可能导致在Android7.0以下的设备无法安装。
方式二:通过命令行完成apk签名
打开Project Stucture图形化界面:
选中app这个module,然后切换到singning标签栏,紧接着点击添加,然后生成release签名信息,紧接着点击”OK”。
切换到Build Types标签,将Signing config选择为”release”,即将刚刚生成的release签名信息配置进去。
操作完成之后,可以看到app这个module的build.gradle文件代码:
【三、apktool反编译工具】
1、apktool简介、配置
apktool是Google提供的apk编译工具,能够反编译及回编译apk,同时安装反编译系统apk所需要的framework-res框架,清理上次反编译文件夹等功能。
第一步:检测是否配置成功:在cmd命令行中输入apktool,这是配置成功的界面
第二步:将要反编译的apk存放在一个文件夹中,并在命令行中切换到文件夹路径。
apktool ifframework-res.apk 为apktool安装框架,框架就会自动安装好。
2、apk反编译与回编译
(1). apktoold xxx.apk 反编译命令,xxx.apk就是在欲反编译的apk文件
C:\***\apktools
发现一个新的文件夹,这个文件夹的文字跟你的apk名字一样,里面我们就可以看到xml文件、AndroidManifest.xml和图片等资源文件了。
反编译
反编译后生成的文件文件夹,里边的AndroidManifest.xml及资源文件可直接打开查看,但是java文件被反编译成.smali文件。
(2)apktoolb xxx 回编译命令
apktool还可以将反编译出来的文件重新打包回去,比如修改一些资源文件后重新打包成apk。例如我反编译Test.apk,就会在C:/***/apktool
目录下生成一个Test文件夹,回编译命令就可以这样写“apktool b Test”。回编译完成会在Test文件夹生成一个dist文件夹和一个build文件夹。
dist文件夹里面存放的就是回编译后不带有签名的apk文件。
build文件夹里面还有一个apk文件夹,里面存放的就是回编译后没有打包成apk的文件。
【四、Android应用签名查看、验证与防止重打包】
1、如何查看应用签名
方式一:窗口命令操作
使用解压工具解压APK文件,在META-INF文件夹拿到CERT.RSA文件。假设CERT.RSA文件的路径是C:\Users\Administrator\Desktop\**\CERT.RSA
。
在CMD中输入
keytool -printcert -fileC:\Users\Administrator\Desktop\**\CERT.RSA
,就可以得到签名信息了
2、默认签名的数字证书(debug.keystore)
为了方便我们开发调试程序,ADT会自动的使用debug密钥为应用程序签名。debug密钥是一个名为debug.keystore的文件,它的位置:C:\***\***\debug.keystore
3、如何生成未经签名的apk
有的时候需要对apk进行再签名,或者用第三方工具来进行签名,这时需要生成出没有签名的apk文件,我们利用AS来生成。其实就是在配置签名信息前打出的包,生成的APK在:…/YourProject/app/build/outputs/apk/app-debug.apk
。
4、android签名校验,防止重打包
反编译dex修改重新打包签名后apk的签名信息肯定会改变,所以可以在代码中判断签名信息是否被改变过,如果签名不一致就退出程序,以防止apk被重新打包。
(1). java代码中验证签名
用PackageManager获取签名信息,比较容易破解,直接修改smali文件可以绕过。
(2). 签名验证放到native层用NDK开发
这种验证稍微安全了一点,毕竟逆向C和C++的人要少一些。
(3). 验证放到服务端