[转]Android APK签名原理及方法
准备知识:数据摘要
这个知识点很好理解,百度百科即可,其实他也是一种算法,就是对一个数据源进行一个算法之后得到一个摘要,也叫作数据指纹,不同的数据源,数据指纹肯定不一样,就和人一样。
消息摘要算法(Message Digest Algorithm)是一种能产生特殊输出格式的算法,其原理是根据一定的运算规则对原始数据进行某种形式的信息提取,被提取出的信息就被称作原始数据的消息摘要。
著名的摘要算法有RSA公司的MD5算法和SHA-1算法及其大量的变体。
消息摘要的主要特点有:
1)无论输入的消息有多长,计算出来的消息摘要的长度总是固定的。例如应用MD5算法摘要的消息有128个比特位,用SHA-1算法摘要的消息最终有160比特位的输出。
2)一般来说(不考虑碰撞的情况下),只要输入的原始数据不同,对其进行摘要以后产生的消息摘要也必不相同,即使原始数据稍有改变,输出的消息摘要便完全不同。但是,相同的输入必会产生相同的输出。
3)具有不可逆性,即只能进行正向的信息摘要,而无法从摘要中恢复出任何的原始消息。
一 Android签名机制及原理
Android系统在安装APK的时候,首先会检验APK的签名,如果发现签名文件不存在或者校验签名失败,则会拒绝安装,所以应用程序在发布之前一定要进行签名。给APK签名可以带来以下好处:
应用程序升级
如果想无缝升级一个应用,Android系统要求应用程序的新版本与老版本具有相同的签名与包名。若包名相同而签名不同,系统会拒绝安装新版应用。
应用程序模块化
Android系统可以允许同一个证书签名的多个应用程序在一个进程里运行,系统实际把他们作为一个单个的应用程序。此时就可以把我们的应用程序以模块的方式进行部署,而用户可以独立的升级其中的一个模块。
代码或数据共享
Android提供了基于签名的权限机制,一个应用程序可以为另一个以相同证书签名的应用程序公开自己的功能与数据,同时其它具有不同签名的应用程序不可访问相应的功能与数据。
应用程序的可认定性
签名信息中包含有开发者信息,在一定程度上可以防止应用被伪造。例如网易云加密对Android APK加壳保护中使用的“校验签名(防二次打包)”功能就是利用了这一点。
签名原理
对一个APK文件签名之后,APK文件根目录下会增加META-INF目录,该目录下增加三个文件:
MANIFEST.MF
NETEASE.RSA
NETEASE.SF
其中.RSA文件还可能是.DSA文件,RSA与SF文件的文件名可以更改,但是它们的命名必须一样。
MANIFEST.MF中保存了APK里所有文件的SHA1校验值的BASE64编码,格式如下(一个文件对应一条记录):
Name: res/anim/abc_fade_in.xml
SHA1-Digest: ohPEA4mboaFUu9LZMUwk7FmjbPI=
Name: res/anim/abc_fade_out.xml
SHA1-Digest: MTJWZc22b5LNeBboqBhxcQh5xHQ=
SF文件里保存了MANIFEST.MF文件的SHA1校验值的BASE64编码,同时还保存了MANIFEST.MF中每一条记录的SHA1检验值BASE64编码,格式如下:
SHA1-Digest-Manifest: ZRhh1HuaoEKMn6o21W1as0sMlaU=
Name: res/anim/abc_fade_in.xml
SHA1-Digest: wE1QEZhFkLBWMw4TRtxPdsiMRtA=
Name: res/anim/abc_fade_out.xml
SHA1-Digest: MfCV1efdxSKtesRMF81I08Zyvvo=
RSA文件则包含了签名的公钥、签名所有者等信息,还保存了http://my.oschina.net/u/816213/blog/685762?fromerr=RSS3IhKo用SHA1withRSA签名算法对SF文件的签名结果信息。
Android系统就是根据这三个文件的内容对APK文件进行签名检验的。
二 Android 签名方法
1、apksign、jarsinger
一般的签名过程可以由apksign.jar或者jarsinger.jar完成。apksign.jar由Android SDK提供,使用方法如下:
java -jar signapk.jar testkey.x509.pem testkey.pk8 update.apk update_signed.apk
它接受一个PEM公钥文件,PK8私钥文件,对update.apk进行签名,签名后的文件保存到update_signed.apk。
jarsinger是由JDK提供,使用方法如下:
jarsigner -verbose -keystore d:\\debug.keystore -signedjar update_signed.apk update.apk androiddebugkey -digestalg SHA1 -sigalg MD5withRSA -keypass android -storepass android
其中:
-keystore表示keystore文件的路径
androiddebugkey 表示keystore中的一个别名
-digestalg表示摘要算法
-sigalg 表示签名算法
-keypass 表示别名密码
-storepass表示keystore密码
经过测试,发现以上两个传统的签名工具存在以下缺点:
1)、jarsigner在对一个已经有META-INF目录的APK进行签名的时候,有可能会报错:
jarsigner: 无法对 jar 进行签名: java.util.zip.ZipException: invalid entry compressed size (expected 1368 but got 1379 bytes)
2)、如果APK中已经有签名文件且签名文件中的RSA(或DSA)、SF文件的命名不是CERT的时候,用这两个签名工具进行签名后,会出现:
META-INF目录下会有两个RSA/SF文件,会导致APK在安装的时候失败。
3)、签名花费时间长。这两个签名工具在生成签名后的APK时,是按Zip中一个entry接一个entry 依次拷贝的,效率十分低。因为游戏类型APK类文件数量一般比较多,所以这一缺陷在签名游戏类型APK时,体现得尤为明显。
2、极速签名工具(ApkSinger)
极速签名工具克服了signapk.jar与jarsigner在签名过程的缺点,使用方法:
java -jar ApkSigner.jar [-appname test] -keystore keystorePath -alias alias [-pswd password] [-aliaspswd aliasPassword] apkPath(or directory)
-appname 待签名的应用程序名,可选,但建议不同的APP填上对应的app名
-keystore 后跟.keystore签名文件
-alias 后跟签名别名
-pswd 后跟对应签名的密码,可选,如果不填,则签名的时候需要手动输入
-aliaspswd 对应别名alias的密码,如果没有则默认使用keystore Password
最后跟待签名的APK路径或者目录路径 ,如果跟的是目录则是批量签名.
三、为何要这么来签名
上面我们就介绍了签名apk之后的三个文件的详细内容,那么下面来总结一下,Android中为何要用这种方式进行加密签名,这种方加密是不是最安全的呢?下面我们来分析一下,如果apk文件被篡改后会发生什么。
首先,如果你改变了apk包中的任何文件,那么在apk安装校验时,改变后的文件摘要信息与MANIFEST.MF的检验信息不同,于是验证失败,程序就不能成功安装。
其次,如果你对更改的过的文件相应的算出新的摘要值,然后更改MANIFEST.MF文件里面对应的属性值,那么必定与CERT.SF文件中算出的摘要值不一样,照样验证失败。
最后,如果你还不死心,继续计算MANIFEST.MF的摘要值,相应的更改CERT.SF里面的值,那么数字签名值必定与CERT.RSA文件中记录的不一样,还是失败。
那么能不能继续伪造数字签名呢?不可能,因为没有数字证书对应的私钥。
所以,如果要重新打包后的应用程序能再Android设备上安装,必须对其进行重签名。
从上面的分析可以得出,只要修改了Apk中的任何内容,就必须重新签名,不然会提示安装失败,当然这里不会分析,后面一篇文章会注重分析为何会提示安装失败。
[转]Android APK签名原理及方法的更多相关文章
- Android : apk签名的多种方法以及key的配置
方法一:使用Android SDK中的签名工具给apk签名: (1)Android源码的 build/target/product/security/ 目录下有 media.pk8.media.x50 ...
- android apk签名原理
//这个md5跟腾讯的对应 public Signature getPackageSignature( ){ Context context=getContext(); String packageN ...
- APK签名原理
网上已有多篇分析签名的类似文章,但是都有一个共同的问题,就是概念混乱,混乱的一塌糊涂. 在了解APK签名原理之前,首先澄清几个概念: 消息摘要 -Message Digest 简称摘要,请看英文翻译, ...
- Android APK 签名比对(转)
Android apk签名的过程 1. 生成MANIFEST.MF文件: 程序遍历update.apk包中的所有文件(entry),对非文件夹非签名文件的文件,逐个生成SHA1的数字签名信息,再用Ba ...
- Android APK 签名 (转发)
Cordova 3.5 为 Android APK 签名,生成可发布的 APK 程序文件 任侠 2014-06-07 00:04 移动开发 抢沙发 16,288 views 目录 [隐藏] ...
- Android apk签名详解——AS签名、获取签名信息、系统签名、命令行签名
Apk签名,每一个Android开发者都不陌生.它就是对我们的apk加了一个校验参数,防止apk被掉包.一开始做Android开发,就接触到了apk签名:后来在微信开放平台.高德地图等平台注册时,需要 ...
- Android apk签名的两种方法
编辑推荐:稀土掘金,这是一个针对技术开发者的一个应用,你可以在掘金上获取最新最优质的技术干货,不仅仅是Android知识.前端.后端以至于产品和设计都有涉猎,想成为全栈工程师的朋友不要错过! 为了保证 ...
- Android apk签名方法介绍
还望支持个人博客站:http://www.enjoytoday.cn 参考博客:http://www.enjoytoday.cn/posts/203 为什么要签名 在介绍签名方法之前,首先我们来了解下 ...
- apk签名原理及实现
发布过Android应用的朋友们应该都知道,Android APK的发布是需要签名的.签名机制在Android应用和框架中有着十分重要的作用. 例如,Android系统禁止更新安装签名不一致的APK: ...
随机推荐
- FZU2150 Fire Game —— BFS
题目链接:https://vjudge.net/problem/FZU-2150 Problem 2150 Fire Game Accept: 2702 Submit: 9240 Time Li ...
- YTU 2456: 评委打分
2456: 评委打分 时间限制: 1 Sec 内存限制: 128 MB 提交: 283 解决: 52 题目描述 一个歌唱比赛,比赛每次会从观众中随即抽取几名观众给分(观众至少有5个,分数为0~1 ...
- poj 1195 Mobile phones 解题报告
题目链接:http://poj.org/problem?id=1195 题目意思:有一部 mobie phone 基站,它的面积被分成一个个小正方形(1 * 1 的大小),所有的小正方形的面积构成了一 ...
- 利用Swoole实现PHP+websocket直播,即使通讯
websocket Websocket只是一个网络通信协议,就像 http.ftp等都是网络通信的协议一样:相对于HTTP这种非持久的协议来说,Websocket是一个持久化网络通信的协议: WebS ...
- WAS:启动服务后,server一会挂起。
有个WAS集成,其中一台因为linux系统异常需要重新安装,于是服务器停了:一会现场提报ERP系统访问不了. 查看了另外一个server后台日志,有一批webcontainer进程挂起,明显服务死了. ...
- iOS NSInteger/NSUInteger与int/unsigned int、long/unsigned long之间的区别!
在iOS开发中经常使用NSInteger和NSUInteger,而在其他的类似于C++的语言中,我们经常使用的是int.unsigned int.我们知道iOS也可以使用g++编译器,那么它们之间是否 ...
- DLL远程注入实例
一般情况下,每个进程都有自己的私有空间,理论上,别的进程是不允许对这个私人空间进行操作的,但是,我们可以利用一些方法进入这个空间并进行操作,将自己的代码写入正在运行的进程中,于是就有了远程注入了. 对 ...
- threesixty.min.js 和jquery.threesixty.js使用总结----实现360度展示
最近公司做一个项目需要360度展示汽车的外观,就用到了threesixty.min.js,自己总结一下使用方法: treesixty.min.js 源码: /*! threesixty-slider ...
- 如何在XCode中更改iPhone或iPad模拟器类型
如何在XCode中更改iPhone或iPad模拟器类型 参考方法一(永久,一旦设置后,每次运行指定的模拟器):(1)选择顶层菜单Project 中的 Set Active Executable(2)根 ...
- 算法练习--LeetCode--54. Spiral Matrix 100%
Spiral MatrixMedium Given a matrix of m x n elements (m rows, n columns), return all elements of t ...