1、Android应用签名机理,什么是签名?Android要求所有已安装的应用程序都使用数字证书做数字签名, 数字证书的私钥由应用开发者持有。Android使用证书作为标识应用程序作者的一种方式, 并在应用程序之间建立信任关系。 证书并不用来控制用户能否安装哪个应用。 证书不需要由证书认证中心签名: 完全可以使用自签名证书(self-signed certificates)。没有正确签名的应用, Android系统不会安装或运行。此规则适用于在任何地方运行的Android系统, 不管是在模拟器还是真实设备上。 因为这个原因, 在真机或模拟器上运行或者调试应用前, 必须为其设置好签名。,为什么需要签
2、名?开发Android的人很多,完全很能把类名、包名起成了同样名字,这时候如何区分?签名可以区分。开发商或恶意开发者可能通过相同的包名混淆替换已安装应用。签名可以保证相同包名但是签名不同的包不被替换。应用如果使用一种key签名,另一个key签名的文件将无法安装 或覆盖老的版本。防止已安装的应用被恶意的第三方覆盖或替换。签名可以防止交易抵赖。,签名策略推荐策略:在应用程序的整个生命周期,所有的应用程序使用相同的证书签名。 Why?主要基于下面几种考虑: 应用程序升级 应用程序模块化 代码/数据 的授权共享- 如何设置签名应用key的有效期? 确认key的有效期要比应用的寿命长, 推荐25年或者更
3、长的有效期。,Debug模式下的签名,当用debug证书签名时, 应用程序不能对外发布。,公开发布应用如何签名?1.使用命令2.使用Eclipse/ADT3.使用ANT,1.使用命令(1)获取一个合适的私钥(2)在release模式下编译应用程序(3)使用你的私钥对应用程序进行签名(4)使用zipalign来调整和优化APK包,(1)获取一个合适的私钥 通过Keytool生成一个自签名的key。,$ keytool -genkey -v -keystore my-release-key.keystore -alias alias_name -keyalg RSA -keysize 2048 -
4、validity 10000,(2)在release模式下编译应用程序,使用Eclipse 要从Eclipse导出一个未签名的 .apk, 在Package Explorer中的project上点击鼠标右键, 选择Android Tools Export Unsigned Application Package。然后给未签名的.apk指定一个文件路径。 (或者在Eclipse中打开AndroidManifest.xml文件, 点开Overview标签, 然后点击Export an unsigned .apk.) 注意, 完全可以在Export Wizard中执行整个的编译和签名步骤。,(3)使
5、用你的私钥对应用程序进行签名,运行Jarsigner对应用签名, 同时引用应用的.apk和用来签名.apk的私钥的keystore。,签名例子: $ jarsigner -verbose -keystore my-release-key.keystore my_application.apk alias_name检查签名是否成功: $ jarsigner -verify my_signed.apk检查签名详细信息: $ jarsigner -verify -verbose -certs my_application.apk,(4)使用zipalign来调整和优化APK包,安装在某个设备上时,
6、确保4字节边界对齐的方式, 提供了性能上的优化。当对齐后, 如果它们包含有对齐限制的二进制数据, Android系统甚至可以使用mmap()读取文件, 而不是从包里复制所有的数据.。另一个好处是在运行程序时, 减少了内存消耗。,zipalign 工具由Android SDK提供, 在 tools/ 目录中。 要调整对齐签名后的.apk, 执行如下命令: $ zipalign -v 4 your_project_name-unaligned.apk your_project_name.apk警告: 在使用zipalign优化包之前, 输入的.apk 必须使用私钥签名过。如果在zipalign之后
7、签名, 将使之前优化对齐操作无效, 回到未优化的状态。,2.使用Eclipse/ADT 如果使用Eclipse和ADT插件, 可以用Export Wizard来导出一个签名的.apk(如果必要,甚至可以创建一个新的keystore.) Export Wizard为你处理所有Keytool和Jarsigner的交互操作, 这允许使用一个GUI界面来操作签名包的过程, 而不必人工处理各种编译, 签名, 以及优化对齐工作。 一旦向导编译并签名完.apk包, 它将也使用zipalign对包进行优化对齐处理. 因为Export Wizard使用到Keytool和Jarsigner, 应当确保在电脑上可以
8、访问到这2样工具。 (1)在Package Explorer中选中project, 然后选择File Export (2)打开Android文件夹, 选择Export Android Application, 然后点击 Next (3) Export Android Application 向导开始, 它将引导你进行签名的整个过程, 包括选择用于签名.apk的私钥(或者创建一个新的keystore和私钥) (4)完成Export Wizard后, 应用程序将被编译, 签名, 对齐, 做好了发布前的所有准备,保证私钥安全下面是一些保证key的安全性的小提示。 对keystore和key采用强密码
9、 当用Keytool生成key时, 不要在命令行提供-storepass 和 -keypass 选项参数。如果非这么做, 你的密码将能够在shell历史中查到, 这样将导致任何用户都能访问 类似地, 当使用Jarsigner签名应用时, 不要在命令行提供-storepass 和 -keypass参数选项 不要给任何人你的私钥, 不要让未经授权的人知道你的keystore和key密码,系统签名Auto-Sign工具的一条批处理命令: java -jar signapk.jar testkey.x509.pem testkey.pk8 update.zip update_signed.zip这条命
10、令的意义是: 通过signapk.jar这个可执行jar包,以testkey.x509.pem这个公钥文件和testkey.pk8这个私钥文件对update.apk进行签名,签名后的文件保存为update_signed.apk”。,系统签名signapk.jar是Android源码包中的一个签名工具。由于Android是个开源项目,所以,很高兴地,我们可以直接找到signapk.jar的源码!路径为/build/tools/signapk/SignApk.java。对比一个没有签名的APK和一个签名好的APK,我们会发现,签名好的APK包中多了一个叫做META-INF的文件夹。里面有三个文件,
11、分别名为MANIFEST.MF、CERT.SF和CERT.RSA。signapk.jar就是生成了这几个文件(其他文件没有任何改变。因此我们可以很容易去掉原有签名信息)。,系统签名1.生成MANIFEST.MF文件 关键代码如下:(1) Manifest manifest = addDigestsToManifest(inputJar); (2) je = new JarEntry(JarFile.MANIFEST_NAME); (3) je.setTime(timestamp); (4) outputJar.putNextEntry(je); (5) manifest.write(outpu
12、tJar);这里简单介绍下SHA1数字签名。简单地说,它就是一种安全哈希算法,类似于MD5算法。它把任意长度的输入,通过散列算法变成固定长度的输出(这里我们称作“摘要信息”)。你不能仅通过这 个摘要信息复原原来的信息。另外,它保证不同信息的摘要信息彼此不同。因此,如果你改变了apk包中的文件,那么在apk安装校验时,改变后的文件摘要信 息与MANIFEST.MF的检验信息不同,于是程序就不能成功安装。,系统签名2.生成CERT.SF文件 对前一步生成的Manifest,使用SHA1-RSA算法,用私钥进行签名。关键代码如下: (1)Signature signature = Signature
13、.getInstance(“SHA1withRSA“); (2) signature.initSign(privateKey); (3) je = new JarEntry(CERT_SF_NAME); (4) je.setTime(timestamp); (5) outputJar.putNextEntry(je); (6) writeSignatureFile(manifest, (7) new SignatureOutputStream(outputJar, signature); RSA是一种非对称加密算法。用私钥通过RSA算法对摘要信息进行加密。在安装时只能使用公钥才能解密它。解密之
14、后,将它与未加密的摘要信息进行对比,如果相符,则表明内容没有被异常修改。,系统签名3.生成CERT.RSA文件 生成MANIFEST.MF没有使用密钥信息,生成CERT.SF文件使用了私钥文件。那么我们可以很容易猜测到,CERT.RSA文件的生成肯定和公钥相关。 CERT.RSA文件中保存了公钥、所采用的加密算法等信息。核心代码如下: (1)je = new JarEntry(CERT_RSA_NAME); (2)je.setTime(timestamp); (3)outputJar.putNextEntry(je); (4)writeSignatureBlock(signature, pub
15、licKey, outputJar);,系统签名好了,分析完APK包的签名流程,我们可以清楚地意识到: 1、 Android签名机制其实是对APK包完整性和发布机构唯一性的一种校验机制。 2、 Android签名机制不能阻止APK包被修改,但修改后的再签名无法与原先的签名保持一致。(拥有私钥的情况除外)。 3、 APK包加密的公钥就打包在APK包内,且不同的私钥对应不同的公钥。换句话言之,不同的私钥签名的APK公钥也必不相同。所以我们可以根据公钥的对比,来判断私钥是否一致。,几个问题:1.流氓软件是怎么打造不死之身的?2.如何将我们需要的日志写到文件里面?3.Android应用如何实现重启系统?4.Android应用如何获取系统签名和权限?,参考链接:http:/ http:/ http:/ http:/ http:/ http:/