Android安全机制分析,及应用程序签名机制

来源:互联网 发布:excel03查找重复数据 编辑:程序博客网 时间:2024/05/17 04:12

原文链接:http://www.2cto.com/Article/201308/237263.html

Android安全机制分析

Android系统是基于Linux内核开发的,因此,Android系统不仅保留和继承了Linux操作系统的安全机制,而且其系统架构的各个层次都有独特的安全特性[2] 。

1. Linux内核层安全机制

Android的Linux内核包含了强制访问控制机制和自主访问控制机制。强制访问控制机制由Linux安全模块来实现,但Google出于某种原因,并没有将LSM编译进Android内核。自主访问控制机制通常由文件访问控制来实现,Linux文件系统的权限控制是由user、group、other与读(r) 、写(w) 、执行(x)的不同组合来实现的。这样,每个文件都有三个基本权限集,它们的组合可以容许、限制、拒绝用户、用户组和其他用户的访问。通常,只有uid是“system”或“root”用户才拥有Android系统文件的访问权限,而应用程序只有通过申请Android权限才能实现对相应文件的访问,也正因为此,Android使用内核层Linux的自主访问控制机制和运行时的Dalvik虚拟机来实现Android的“沙箱”机制。

2. Android的“沙箱”机制

Android“沙箱”的本质是为了实现不同应用程序和进程之间的互相隔离,即在默认情况下,应用程序没有权限访问系统资源或其它应用程序的资源。每个APP和系统进程都被分配唯一并且固定的User Id,这个uid与内核层进程的uid对应。每个APP在各自独立的Dalvik虚拟机中运行,拥有独立的地址空间和资源。运行于Dalvik虚拟机中的进程必须依托内核层Linux进程而存在,因此Android使用Dalvik虚拟机和Linux的文件访问控制来实现沙箱机制,任何应用程序如果想要访问系统资源或者其它应用程序的资源必须在自己的manifest[23]文件中进行声明权限或者共享uid。

3. Android的权限检查机制

Android是一个“权限分离”的系统,任何一个应用程序在使用Android受限资源(网络、电话、短信、蓝牙、通讯录、SdCard等)之前都必须以XML文件的形式事先向Android系统提出申请,等待Android系统批准后应用程序方可使用相应的资源,权限与Java的API是多对多的映射关系。

当Android应用程序获得相应权限后,它就能通过调用API来完成相应的功能。一个API调用可被分为三个步骤[3]:第一,应用程序获取相应权限后会调用公共库中的API;第二,公共API会调用一个叫API代理的接口(RPC stub);第三,RPCstub把请求以IPC绑定的形式传递给系统服务,由系统服务进程完成具体的功能,权限检查恰恰发生在对系统服务和系统进程中。权限检查不仅包括安装时的静态检查,还包括APP运行时的动态检查。动态检查是指APP在运行期间调用的系统服务或系统组件需要经过授权检查。动态检查并不发生在APP本身,而是发生在系统服务或系统组件的进程中。在Android4.0版本之前,Android的权限检查机制是可以被绕过的,这是因为权限检查机制存在漏洞,即调用者不需要具有被调用者的相关权限,Android4.0版本不仅使用函数“checkUidPermission”来决定权限是否应授予相应的进程而且使用了函数“checkCallingPermission”来检查调用者是否有相应的权限。因此,Android权限机制一般不能被绕过,但Android权限机制有些不容忽视的缺陷,具体表现在如下几个方面:

第一,权限一经授予应用程序,那么此权限在该应用程序生命期间都将有效,用户无法剥夺权限;

第二,权限机制缺乏灵活性,要么全都批准应用程序所要求的所有权限,要么拒绝应用程序的安装;

第三,权限机制安全性不够,不能阻止恶意软件通过JNI技术直接调用C库,从而获取系统服务。

4. Android的数字签名机制

所有安装到Android系统中的应用程序都必须拥有一个数字证书[4],此数字证书用于标识应用程序的作者和应用程序之间的信任关系。Android系统不会安装一个没有数字证书的应用程序,如果一个权限的保护级别为signature,只有当应用程序所用数字签名与声明此权限的应用程序所用数字签名相同时,Android系统才会授权。如果一个权限的保护级别为signatureOrSystem,Android系统会将该权限授予具有相同数字签名的应用程序或Android包类。

 

 

原文链接:http://book.51cto.com/art/201305/395995.htm

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

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

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

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

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

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方法实现,具体代码如下:

private static Manifest addDigestsToManifest(JarFile jar)  {   ……   //遍历update.apk包中所有文件   //得到签名文件内容   InputStream data = jar.getInputStream(entry);    //更新文件内容   while ((num = data.read(buffer)) > 0) {    md.update(buffer, 0, num);   }   ……      //进行SHA1签名,并采用Base64进行编码   attr.putValue("SHA1-Digest", base64.encode(md.digest()));   output.getEntries().put(name, attr);   ……  } 

 

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

(2)生成CERT.SF文件

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

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

 

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

(3)生成CERT.RSA文件

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

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

 

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

 

 

原创粉丝点击