当前位置:首页 » 其他

关于APK签名的一些东西

2014-12-23 14:53 本站整理 浏览(15)

什么是APK

了解APK签名之前,首先要知道什么是apk文件:APK是AndroidPackage的缩写,即Android安装包(apk),APK文件其实就是zip格式的文件,只是后缀被改为了apk,所以用任何能解压zip的软件都可以直接把一个APK文件解压出来,解压出来的东西如图(已签名的APK):


APK签名

APK签名的意义

安全,每个发布的Android应用在升级的时候都需要保证签名和包名必须相同,这样如果有人使用了不一致的签名或篡改了我们的发布的apk包,系统将拒绝进行升级
权限管理,Android提供了基于签名的权限机制,一个应用程序可以为另一个以相同证书签名的应用程序公开自己的功能,从而实现应用程序间以安全的方式共享代码和数据,具体可以参看<Permission>标签
模块化,Android系统可以允许同一个证书签名的多个应用程序在一个进程里运行,系统实际把他们作为一个单个的应用程序,此时就可以把我们的应用程序以模块的方式进行部署,而用户可以独立的升级其中的一个模块

APK签名的原理

目录结构

从我们解压出来的APK目录里面可以看到有一个META-INF目录,里面保存的三个文件就是我们签名过程中生成的东西,就是这仨货:

MANIFEST.MF:所有文件的摘要信息,但不包括它们仨自己
CERT.SF:保存的是MANIFEST.MF的摘要值,以及MANIFEST.MF中每一个摘要项的摘要值
CERT.RSA:保存的是利用密钥对CERT.SF进行加密生成的数字签名和签名时用到的数字证书,数字证书保存的就是公钥和签名算法

签名过程

对APK签名的过程可以简单归结如下:首先利用SHA-1摘要生成算法对我们所有的文件生成摘要信息,然后利用密钥对我们的摘要信息进行加密数字签名,最后把未加密的摘要信息、数字签名和签名所用的数字证书(公钥、加密算法、发布者等)一起发布出来,生成最后的签名APK文件,整个过程如图所示:

Android系统在验证的时候会根据数字证书提供的公钥和解密算法进行解密,然后拿解密出来的摘要信息(hash序列)与手机本地文件生成的摘要信息进行比对,如果之前APK被篡改或所用签名与发布时不一致,就会导致解密出来的摘要信息与本地不一致,从而达到验证的目的.
对三个文件生成的过程及源码分析,有兴趣的同学可以参考这个:/content/1527686.html

相关概念

签名的过程涉及到了很多摘要算法、数字签名等概念,下面先对它们一一进行说明,熟悉的同学可以略过

消息摘要

维基百科:http://en.wikipedia.org/wiki/Message_digest
百度百科:http://baike.baidu.com/link?url=W926rkCvewjKzCRSLiqIALuQv11MbL1CM1IdeS_rmAKEpyLAp1AWZMj9rLiYt7FUQ2XorChF6zhWn6REVolcmzHcBNekhkr4M-zThoeS-ertuCT92f6uTqCRUolR-jvx
简单的说消息摘要就是在消息数据上,执行一个单向的Hash函数,生成一个固定长度的Hash值,这个Hash值即是消息摘要也称为数字指纹:
消息摘要有以下特点:
1. 通过摘要无法推算得出消息本身
2. 如果修改了消息,那么摘要一定会变化(实际上,由于长明文生成短摘要的Hash必然会产生碰撞),所以这句话并不准确,我们可以改为:很难找到一种模式,修改了消息,而它的摘要不会变化

数字签名

数字签名就是信息的发送者用自己的私钥对消息摘要加密产生一个字符串,加密算法确保别人无法伪造生成这段字符串,这段数字串也是对信息的发送者发送信息真实性的一个有效证明

数字证书

数字证书是一个经证书授权中心数字签名的包含公开密钥拥有者信息以及公开密钥的文件,最简单的证书包含一个公开密钥、名称以及证书授权中心的数字签名,此外,数字证书只在特定的时间段内有效;
注意,APK签名时用到的数字证书是用户自己在本地生成的,并不需要权威机构的发布或认证,是一个自签名的数字证书

APK签名的方法

对APK包签名的步骤无非就是产生key和签名两步,签名的方法主要有三种:
JDK:JDK中有keytool和jarsigner两个工具,keytool用于产生加密用的key,jarsigner用于对APK进行签名,这两个文件都可以在JAVA的bin目录下找到,操作的方法当然是命令行了

signapk:signapk是Android提供的签名工具,可以在build后的Android源码中找到也可以直接到网上去下,命令行:signapk [-w] publickey.x509[.pem] privatekey.pk8 input.jar soutput.jar publickey.x509.pem里包含的是证书和证书链,证书和证书链中包含了公钥和加密算法;privatekey.pk8是私钥;input.jar是需要签名的jar;output.jar是签名结果
IDE:平常大家打包的方式基本都是IDE帮我们做了,无论是Eclipse还是Intellij Idea(Android Studio),都可以创建自己新的keystore或使用已有的keystore,但无论哪种都需要牢记自己的keystore password和key password,这个就是只属于你自己的密钥了;这两个IDE的操作基本是一样的,略有不同的是Eclipse是在导出项目(Export Project)的时候来做这个事情,而Intellij Idea(Android Studio)是在菜单栏-->build-->Generate Signed APK,而且Intellij Idea(Android Studio)在导出前可能会让你输入一个MASTER KEY,这里随便输一个密码就可以,但是要记住这个密码
这里贴一个Eclispe的操作方法:http://mamicode.com/info-detail-11527.html,网上讲得很清楚了,不在此赘述

其他相关参考资料

Android APK签名对比及说明:/content/3572501.html
Android APK签名过程分析:http://blog.csdn.net/asmcvc/article/details/9311827
Android APK破解:/content/3572506.html