安卓数字签名指的是对apk包做文件摘要并加密,在安装apk包时做解密和验证以保证包体不被篡改。这里先普及下签名和验证流程。签名文件保存在apk包里META-INF目录下,包含3个文件:

1、后缀为MF的是摘要文件。首先遍历apk包,将除META-INF目录外其他所有文件用SHA1生成摘要信息并用base64编码。如果你手动改变了apk包中的文件,那么在apk包安装验证时,改后的文件摘要信息与原MF文件中的不一致,会导致安装失败。

2、后缀为SF还是摘要文件。对上面生成的MF文件做两步处理,首先读取全量摘要文件使用SHA1生成摘要并用base64编码,然后再次读取各文件子项再次做一样的摘要操作。

3、后缀为RSA的是签名文件。数字证书一般存放在钥匙库中,从数字证书中取出私钥,对SF文件使用SHA1-RSA算法进行非对称加密得到RSA文件。在安装时从钥匙库取出数字证书的公钥并解密,再与未加密前的摘要信息进行对比,相符则说明apk包未被篡改。

  问题场景是原来签名正常的apk包突然出现闪退现象。经定位发现该签名包体原来已经签过名,重复签名导致问题发生。排查代码发现,在生成MF文件时调用addDigestsToMainfest方法时没有去掉以上三个文件,导致重复签名时重复计算摘要,安装验证时拿计算后的摘要比较计算前的,必然会出现验证失败。

  举例,首次签名时包里是不存在这三个文件的,所以首次签名会正常生成wlf. MF、wlf.SF和wlf.RSA;第二次签名会把这三个文件也计算进wlf.MF里去,接着按上面逻辑生成另外两个文件,再替换掉原来三个同名文件。而且这时wlf.MF已经改变了,同样其他两个文件也跟着变。那么在验证时拿新的摘要去比对包体里老的摘要,发现这三个文件被替换了,验证也就失败了。第三次重复签名的话这三个文件还会被替换成新的,因为计算后文件又被替换了,以此类推。举个例子,好比你拿着刚办好的二代身份证给人家看,但人家系统里只有你的一代身份证,虽然名字一样,样貌衣着却变了,人家一核对就怀疑你了。而篡改的人就是你自己,这就叫监守自盗了。所以做摘要必须要去掉那三个文件。

安卓apk包重复签名问题的更多相关文章

  1. 查看APK包名签名等信息

    有些游戏第三方比如分享需要配置游戏包名和签名,不同渠道包名签名又不同,所以时常需要查看不同apk包等签名信息,之前是使用等微博开放平台的手机客户端查看apk签名,前提是知道包名,网上找了下查看签名和包 ...

  2. 搭建ionic3-angular5 开发环境并打包成安卓apk包教程

    安装node.js 搭建ionic3-angular5 开发环境,首先查看本地电脑是否安装node环境,打开终端,输入 命令: node -v 没有去安装nodejs  网址:http://nodej ...

  3. 批量修改安卓apk包名

    1.准备工作 1.1 反编译工具apktool下载 1.2 java, android SDK安装 1.2 python安装 2.反编译现有包 apktool.bat d test.apk 3. 直接 ...

  4. Eclipse发布安卓APK包无图标的解决方法

    算是一个Bug,清空项目都不行. 解决方法是卸载掉项目,重新导入.

  5. php获取apk包信息的方法

    /*解析安卓apk包中的压缩XML文件,还原和读取XML内容 依赖功能:需要PHP的ZIP包函数支持.*/ include('./Apkparser.php'); $appObj = new Apkp ...

  6. 【keytool jarsigner工具的使用】Android 使用JDK1.7的工具 进行APK文件的签名,以及keystore文件的使用

    一个android apk的编译过程 请参考: http://www.2cto.com/kf/201312/261475.html 典型的编译过程: aapt( Android Asset Packa ...

  7. IONIC 打包安卓apk详细过程

    参照以下链接: https://blog.csdn.net/qq_20264891/article/details/79319408 当 cordova 项目安装的 android 平台版本 与 系统 ...

  8. mac下自己实现re-sign.jar对apk进行重签名

    利用Robotinum对给的apk文件进行自动化测试,在不知道源码的情况下,只有apk文件如何进行自动化测试呢? 首先需要对apk文件进行重签名,并获得该apk文件的包名和程序入口的类名. 最开始网上 ...

  9. 使用Gradle打出带签名的apk包

    step1:配置build.gradle文件 step1:切换到项目所在目录,用build命令打包 首先 gradle clean 命令清理一下当前项目 E:\AndroidStudioProject ...

随机推荐

  1. Minimum Path Sum,最短路径问题,动态规划

    问题描述:Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right ...

  2. tyvj 1091 等差数列 dp

    P1091 等差数列 时间: 1000ms / 空间: 131072KiB / Java类名: Main 背景 广东汕头聿怀初中 Train#3 Problem 3 描述 等差数列的定义是一个数列S, ...

  3. vmware增加共享文件夹

    增加共享文件夹 VMWare提供共享文件夹功能.前提是在虚拟机中安装VMware tools 1. 安装VMware tools 会自动在虚拟机中的/media/VMware Tools/中有个压缩包 ...

  4. SQLite在C#中的使用

    SQLite是一款轻型的数据库,在一些数据量不太大的程序中,它暂用的资源非常低.支持很多操作系统和许多语言,所以还是很方便的.在C#中,要用的话可以通过网站来下载或者在VS中通过NuGet来下载.这个 ...

  5. AspectJ的Execution表达式

    在使用spring框架配置AOP的时候,不管是通过XML配置文件还是注解的方式都需要定义pointcut"切入点" 例如定义切入点表达式  execution (* com.sam ...

  6. 牛客比赛-Wannafly9-A/B/C

    A-链接:https://www.nowcoder.com/acm/contest/71/A来源:牛客网 给定n个正整数,请找出其中有多少个数x满足:在这n个数中存在数y=kx,其中k为大于1的整数 ...

  7. linux rpm命令安装卸载 初步使用

    安装(以安装jdk为例) 1.下载后,首先把jdk-7u3-linux-x64.rpm复制到/usr/local/src#cp jdk-7u3-linux-x64.rpm /usr/local/src ...

  8. asp.net获取URL和IP地址

    (转自:http://www.cnblogs.com/JuneZhang/archive/2010/11/26/1888863.html) HttpContext.Current.Request.Ur ...

  9. 条款5.了解c++默默编写并且调用了哪些函数。

    如果想在一个内含reference成员的class内支持赋值操作,必须自己定义copy assignment操作符.而且面对“内含有const成员的”class,编译器的反应也是相同的,由于更改con ...

  10. Java中会有内存泄露吗?

    一.Java内存回收机制 不论哪种语言的内存分配方式,都需要返回所分配内存的真实地址,也就是返回一个指针到内存块的首地址.Java中对象是采用new或者反射的方法创建的, 这些对象的创建都是在堆(He ...