Chinaunix首页 | 论坛 | 博客
  • 博客访问: 269023
  • 博文数量: 138
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 971
  • 用 户 组: 普通用户
  • 注册时间: 2015-03-03 10:05
文章分类

全部博文(138)

文章存档

2016年(1)

2015年(137)

我的朋友

分类: Android平台

2015-03-06 20:42:21

应用程序签名机制实现的源代码分析

3.3.2 应用程序签名机制实现的源代码分析

Android采用签名机制来保护应用程序的安全,以便对开发者进行身份鉴别,防止替换应用程序包或篡改内容。同时有助于在应用程序之间建立一种信任关系,可以由同一个私钥签名的若干个应用程序共享代码和数据

Android系统签名主要有ROM签名和应用程序APK签名两种形式。ROM签名是针对已经生成的Android系统ROM包进行签名。应用程序APK签名是针对开发者开发的应用程序安装包APK进行签名。前者是对整个Android系统包签名,后者只对Android系统中一个应用程序APK签名。这里仅对APK签名的执行过程进行代码层面的分析,流程如图3-7所示。

Android 应用程序APK是jar包,签名采用的工具是signapk.jar包,对应用程序安装包签名的执行命令如下:


  1. java -jar signapk.jar publickey privatekey input.apk output.apk   

 

此命令实现了对应用程序安装包input.apk签名的功能。在signapk.jar命令中,第一个参数为公钥publickey,第二个参数为私钥privatekey,第三个参数为输入的包名,第四个参数签名后生成的输出包名。在此命令中,signapk.jar使用公钥publickey和私钥privatekey对input.apk安装包进行签名,生成output.apk包。signapk源码位于build/tools/signapk/SignApk.java中。


完成签名后APK包中多了一个META-INF文件夹,其中有名为MANIFEST.MF、CERT.SF和CERT.RSA的三个文件。MANIFEST.MF文件中包含很多APK包信息,如manifest文件版本、签名版本、应用程序相关属性、签名相关属性等。CERT.SF是明文的签名证书,通过采用私钥进行签名得到。CERT.RSA是密文的签名证书,通过公钥生成的。MANIFEST.MF、CERT.SF和CERT.RSA三个文件所使用的公钥和私钥的生成可以通过 development/tools/make_key 来获得。下面分别介绍MANIFEST.MF、CERT.SF和CERT.RSA三个文件的生成方法。

(1)生成MANIFEST.MF文件

生成MANIFEST.MF是对APK包中所有未签名文件逐个用算法SHA1进行数字签名,再对数字签名信息采用Base64进行编码,最后将编完码的签名写入MANIFEST.MF文件中。添加数字签名到manifest文件通过调用addDigestsToManifest方法实现,具体代码如下:


  1. private static Manifest addDigestsToManifest(JarFile jar)    
  2. {    
  3.  ……    
  4.  //遍历update.apk包中所有文件    
  5.  //得到签名文件内容    
  6.  InputStream data = jar.getInputStream(entry);    
  7.    
  8.  //更新文件内容    
  9.  while ((num = data.read(buffer)) > 0) {    
  10.   md.update(buffer, 0, num);    
  11.  }    
  12.  ……    
  13.     //进行SHA1签名,并采用Base64进行编码    
  14.  attr.putValue("SHA1-Digest", base64.encode(md.digest()));    
  15.  output.getEntries().put(name, attr);    
  16.  ……    
  17. }   

 

需要说明,生成MANIFEST.MF使用了SHA1算法进行数字签名,SHA1是一种Hash算法,两个不同的信息经Hash运算后不会产生同样的信息摘要,由于SHA1是单向的,所以不可能从消息摘要中复原原文。如果恶意程序改变了APK包中的文件,那么在进行APK安装校验时,改变后的摘要信息与MANIFEST.MF的检验信息不同,应用程序便不能安装成功。

(2)生成CERT.SF文件

在生成MANIFEST.MF文件之后,用SHA1-RSA算法对其进行私钥签名,便生成CERT.SF。具体代码如下:


  1. Signature signature = Signature.getInstance("SHA1withRSA");    
  2. signature.initSign(privateKey);    
  3. je = new JarEntry(CERT_SF_NAME);    
  4. je.setTime(timestamp);    
  5. outputJar.putNextEntry(je);    
  6. writeSignatureFile(manifest, newSignatureOutputStream(outputJar, signature));  

 

RSA是目前最有影响力的公钥加密算法,是一种非对称加密算法、能够同时用于加密和数字签名。由于RSA是非对称加密算法,因此用私钥对生成MANIFEST.MF的数字签名加密后,在APK安装时只能使用公钥才能解密它。

(3)生成CERT.RSA文件

生成CERT.RSA文件与生成CERT.SF文件不同之处在于,生成CERT.RSA文件使用了公钥文件。CERT.RSA文件中保存了公钥以及所用的采用加密算法等信息。具体代码如下:


  1. je = new JarEntry(CERT_RSA_NAME);    
  2. je.setTime(timestamp);    
  3. outputJar.putNextEntry(je);    
  4. writeSignatureBlock(signature, publicKey, outputJar);   

 

通过以上对Android应用程序签名的代码分析,可以看出Android系统通过对第三方APK包进行签名,达到保护系统安全的目的。应用程序签名主要用于对开发者身份进行识别,达到防范恶意攻击的目的,但不能有效地限制应用程序被恶意修改,只能够检测应用程序是否被修改过,如果应用程序被修改应该再采取相应的应对措施。

阅读(794) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~