记录之前写的一篇总结。
V1:V1是Android7.0之前的签名方式,使用jar Signature方式对APK进行签名打包,jar Signature来自JDK。APK进行签名时会生成一个META-INF文件夹,里面有三个文件:MANIFEST.MF,CERT.RSA,CERT.SF,是用来记录签名信息的。
除了上述三个文件,其他的文件都会对文件内容做一次SHA1算法,就是计算出文件的摘要信息,然后用Base64进行编码。比如AndroidManifest.xml文件,就会对它进行编码生成SHA-1值,把这个SHA-1值用Base64转化网站转化回去,就是MANIFEST.MF文件中记录的条目值。
因此,MANIFEST.MF中存储的是:逐一遍历里面的所有条目,如果是目录就跳过,如果是一个文件,就用SHA1(或者SHA256)消息摘要算法提取出该文件的摘要然后进行BASE64编码后,作为“SHA1-Digest”属性的值写入到MANIFEST.MF文件中的一个块中。该块有一个“Name”属性,其值就是该文件在apk包中的路径。
不再详细累述,CERT.SF文件做了什么工作:
1.计算这个MANIFEST.MF文件的整体SHA1值,再经过BASE64编码后,记录在CERT.SF主属性块(在文件头上)的“SHA1-Digest-Manifest”属性值值下。
2.逐条计算MANIFEST.MF文件中每一个块的SHA1,并经过BASE64编码后,记录在CERT.SF中的同名块中,属性的名字是“SHA1-Digest”。
CERT.RSA是一个满足PKCS7格式的文件:它会把之前生成的 CERT.SF文件,用私钥计算出签名, 然后将签名以及包含公钥信息的数字证书一同写入CERT.RSA中保存。
总结:V1加密签名后,如果APK文件被篡改后,在APK安装校验时,改变后的文件摘要信息与MANIFEST.MF的检验信息不同,于是验证失败,程序就不能成功安装。
如果你对更改的过的文件相应的算出新的摘要值,然后更改MANIFEST.MF文件里面对应的属性值,那么必定与CERT.SF文件中算出的摘要值不一样,照样验证失败。
如果不死心继续计算MANIFEST.MF的摘要值,相应的更改CERT.SF里面的值,那么数字签名值必定与CERT.RSA文件中记录的不一样,还是失败。
所以,重新打包后的应用程序能再Android设备上安装,必须对其进行重签名。
V2:Android7.0推出了V2签名方式,使用Full Apk Signature方式对APK进行签名打包。
经过对V1的详细介绍,V2就简单明了了。V1是验证单个的ZIP条目,而V2则是验证压缩文件的所有字节码。因此,在签名完成后无法再更改(包括zipalign)。因此,现在在编译过程中,压缩、调整和签署合并成一步完成。好处是,更安全而且新的签名可缩短在设备上进行验证的时间(不需要费时地解压缩然后验证),从而加快应用安装速度。当然只在Android7.0以上的手机才会使用这种验证方式。
总结:
如
选择V1还是V2?
只选择V1,还是依照旧的签名方式,不会有任何影响,只是在Android7.0以上的手机上不会使用更安全的验证方式。
只选择V2,在Android7.0以上的手机没问题,但是由于7.0以下的系统没有这种新的验证方式,因此会提示未安装。
同时选择V1和V2,在Android7.0以下的手机会使用V1验证,7.0以上的会使用V2方式验证,因此都没问题。
新的问题(多渠道打包)
由于Android市场众多,因此需要标记不同的渠道包。
目前使用的方案是:使用V1签名方式,美团Python脚本批量打包,它的原理就是生成一个全新的文件,把APK进行解压遍历复制进去,复制中通过在META-INF目录下添加空文件,用空文件的名称来作为渠道的唯一标识,之前在META-INF下添加文件是不需要重新签名应用的,因此批量打出的包在Android上是可以校验通过的。
但是如果使用的V2方式,在新的应用签名方案下META-INF已经被列入了保护区了,那么Python脚本批量打出的包就会造成Android7.0上校验不通过,这便是之前我们遇到的问题。
虽然只使用V1签名验证不会影响什么,但V2是谷歌爸爸推荐的签名方式,肯定是要慢慢用起来的,一路高歌走向安全规范化的道路。
美团推出了针对V2的新一套批量打包方式,并生成了插件,可以使用Gradle快速集成。
Walle(瓦力)https://github.com/Meituan-Dianping/walle
walle.png可扩展的APK Signature Scheme v2 Block
V2的签名信息是以ID(0x7109871a)的ID-value来保存在这个区块中,通过Android源代码可以看出Android是通过查找ID为 APK_SIGNATURE_SCHEME_V2_BLOCK_ID = 0x7109871a 的ID-value,来获取APK Signature Scheme v2 Block,对这个区块中其他的ID-value选择了忽略。
因此美团是通过提供一个自定义的ID-value并写入该区域,从而为快速生成渠道包服务,每打一个渠道包只需复制一个APK,然后在APK中添加一个ID-value即可。
所以,我们可以考虑采用这用新的方式来打渠道包了。
参考链接:
https://tech.meituan.com/android-apk-v2-signature-scheme.html
http://blog.csdn.net/u011904605/article/details/52058971
http://www.jianshu.com/p/a27783a713f2
http://www.jianshu.com/p/e1e2fd05bb62
关于上次分享的APK加壳概念:
一、什么是加壳?
加壳是在二进制的程序中植入一段代码,在运行的时候优先取得程序的控制权,做一些额外的工作。大多数病毒就是基于此原理。是应用加固的一种手法对原始二进制原文进行加密/隐藏/混淆。
示例.png1、需要加密的Apk(源Apk)
2、壳程序Apk(负责解密Apk工作)
3、加密工具(将源Apk进行加密和壳Dex合并成新的Dex)
加壳程序就是把要加壳的apk放入解壳程序的dex文件中。
解壳程序是最后替代我们apk安装到手机中运行的程序。它在执行中从自己的dex中释放出我们apk程序。
二、加壳作用
加壳的程序可以有效阻止对程序的反汇编分析,其实就是鱼目混珠。
参考链接:
网友评论