http://blog.csdn.net/qianfu111/article/details/9113887
http://blog.csdn.net/qianfu111/article/details/9113887
http://blog.csdn.net/qianfu111/article/details/9113887
签名的必要性
1、 防止你已安装的应用被恶意的第三方覆盖或替换掉。
2、 开发者的身份标识,签名可以防止抵赖等事件的发生。
开发Android的人这么多,完全有可能大家都把类名,包名起成了一个同样的名字,这时候如何区分?签名这时候就是起区分作用的。另外由于开发商可能通过使用相同的Package Name来混淆替换已经安装的程序,签名这时可以可以防止你已安装的应用被恶意的第三方覆盖或替换掉。因而APK如果使用一个key签名,发布时另一个key签名的文件将无法安装或覆盖老的版本。
签名方式
签名有很多种方式,常见的有:
1、 在Eclipse下通过插件获取数字证书,并签名你的应用。
打开Eclipse->选择你要签名的项目->右击->android tools->Export signedApplication package,再进行相关操作。这里首先需要创建数字证书,然后再利用数字证书签名你的应用。
运气好时,你会发现签名失败,却怎么也找不到原因。本人之前就遇到过这种情况,也困惑过好久,最终才发现是插件出问题了,抓狂。那你不妨使用下面一种方法。
2、 用KeyTool产生数字证书文件,再签名你的应用。
命令:
- keytool -genkey -v -keystore D:\Users\Administrator\Desktop\mytest.keystore-alias mytest -keyalg RSA -validity 20000
其中参数含义如下:
- -keystore D:\Users\Administrator\Desktop\mytest.keystore表示生成的证书及其存放路径,默认在用户主目录下;
- -alias mytest 表示证书的别名是mytest;
- -keyalg RSA 表示采用的RSA算法;
- -validity 20000表示证书的有效期是20000天。
这样你就会在相应目录下获得所需的数字证书,如上图所示。
获取到数字证书之后,你就可以用数字证书去签名你的应用,签名步骤如下:
右击工程 --> 选择Android Tools --> Export Signed Application Package --> 选择next --> 选择Use existing keystore,并填写数字证书位置,以及密码,再next --> using existing key,选择alias,以及密码,再next --> 选择程序存放位置后完成。
补充:
有时你可能还需要得到证书指纹(MD5和SHA1)。
1、获取证书指纹(MD5)命令:
- keytool -list -alias mytest -keystore D:\Users\Administrator\Desktop\mytest.keystore
2、获取证书指纹(SHA1)命令:
- keytool -v -alias mytest -keystore D:\Users\Administrator\Desktop\mytest.keystore
3、这两条命令只是参数不同,你也可以同时获取证书指纹(MD5和SHA1),当然-alias后面的别名一定要跟前面的对应。命令如下图所示:
数字证书简介:
Android数字证书包含以下几个要点:
在Android系统中,所有安装到系统的应用程序都必有一个数字证书,此数字证书用于标识应用程序的作者和在应用程序之间建立信任关系,不是用来决定最终用户可以安装哪些应用程序,数字证书的私钥则保存在程序开发者的手中。这个数字证书并不需要权威的数字证书签名机构认证,它只是用来让应用程序包自我认证的。如果一个permission的protectionLevel为signature,那么就只有那些跟permission所在的程序拥有同一个数字证书的应用程序才能取得该权限。
Android使用Java的数字证书相关的机制来给apk加盖数字证书,要理解android的数字证书,需要先了解以下数字证书的概念和java的数字证书机制。Android系统要求每一个安装进系 统的应用程序都是经过数字证书签名的, Android将数字证书用来标识应用程序的作者和在应用程序之间建立信任关系。
(1)所有的应用程序都必须有数字证书,Android系统不会安装一个没有数字证书的应用程序。
(2)Android程序包使用的数字证书可以是自签名的,不需要一个权威的数字证书机构签名认证。
(3)如果要正式发布一个Android,必须使用一个合适的私钥生成的数字证书来给程序签名 ,而不能使用adt插件或者ant工具生成的调试证书来发布。
Android的开发工具(ADT插件和Ant)都可以协助开发者给apk程序签名,它们都有两种模式:调试模式(debug mode)和发布模式(release mode)。在调试模式下,android的开发工具会在每次编译时使用调试用的数字证书(default.keystore)给程序签名,开发者无须关心。当要发布程序时,开发者就需要使用自己的数字证书给apk包签名。因此,当我们在开发微信分享功能时候,需要使用发布模式。如果不使用自己生成的数字证书,你将只能在第一次分享成功,以后就一直调不出分享的界面。
(4)数字证书都是有有效期的,Android只是在应用程序安装的时候才会检查证书的有效期。如果程序已经安装在系统中,即使证书过期也不会影响程序的正常功能。Android Market强制要求所有应用程序数字证书的有效期要持续到2033年10月22日以后。
(5)Android使用标准的java工具Keytool和Jarsigner来生成数字证书,并给应用程序包签名。
(6)使用zipalign优化程序。
有关签名密钥(证书)与发行包名变化可能有如下限定:
下面是我自己测试的结果,跟网上的一些资料有些出入,个人认为包主要判断是否属于同一应用,然后签名用来判断程序所属者,判断是否属于不同版本。有任何问题,欢迎轻拍。
1、包名相同,签名相同:安装时可覆盖安装(就是同一程序同一版本)。
2、包名相同,签名不同:Android认为版本发生了变化,需先卸载再安装(同一程序不同版本)。
3、包名不同,签名相同:正常安装。
4、包名不同,签名不同:正常安装。
程序覆盖安装检查:
(1)、两个程序的入口Activity是否相同。两个程序如果包名不一样,即使其它所有代码完全一样,也不会被视为同一个程序的不同版本;
(2)、两个程序所采用的签名是否相同。如果两个程序所采用的签名不同,即使包名相同,也不会被视为同一个程序的不同版本,不能覆盖安装。
总结一下就是:签名、包名相同,需覆盖安装。
这里有一个很简单的例子:当我们在公司开发时,在自己电脑上调试的手机,多次调试时不需要卸载(此时是覆盖安装)。而当其他人拿了这个手机去他电脑上调试时,就需要先卸载该程序(必须卸载安装)。当你以前的程序是采用默认签名的方式(即debug签名),一旦换了新的签名应用将不能覆盖安装,必须将原先的程序卸载掉,才能安装上。
因此使用debug签名的应用:无法在Android市场销售;而且,不同机器生成的debug密钥不同,不利apk升级和维护;debug签名有一年有效期。使用独立签名的应用:可在Android市场销售,签名固定会更加便利apk升级和维护。
参考资料:
http://blog.csdn.net/wirelessqa/article/details/7651613
http://blog.csdn.net/lyq8479/article/details/6401093
http://blog.csdn.net/wenlin56/article/details/8153301-
Android数字证书具体应用机制
- http://developer.51cto.com 2010-01-26 14:38 佚名 CSDN 我要评论(1)
- Android数字证书的作用是非常重要的。Android操作系统每一个应用程序的安装都需要经过这一数字证书的签名。
Android手机操作系统作为一款比较流行的开源系统在手机领域占据着举足轻重的地位。 在Android系统中,所有安装到系统的应用程序都必有一个Android数字证书,此数字证书用于标识应用程序的作者和在应用程序之间建立信任关系,如果一个permission的protectionLevel为signature,那么就只有那些跟该permission所在的程序拥有同一个数字证书的应用程序才能取得该权限。
Android使用Java的数字证书相关的机制来给apk加盖数字证书,要理解Android数字证书,需要先了解以下数字证书的概念和java的数字证书机制。
基础概念:数字证书:
数字证实是采用数字手段来证实用户身份的一种方法。数字证书含有两部分数据:一部分是对应主体(单位或个人)的信息,另一部分是这个主体所对应的公钥。即数字证书保存了主体和它的公钥的一一对应关系,用于自我认证(向其他的用户证明自己的身份)。
Java数字证书工具。
Java中的keytool.exe可以用来创建数字证书,所有的数字证书是以一条一条(采用别名区别)的形式存入证书库的中,证书库中的一条证书包含该条证书的私钥,公钥和对应的数字证书的信息。证书库中的一条证书可以导出数字证书文件,数字证书文件只包括主体信息和对应的公钥。
每一个证书库是一个文件组成,它有访问密码,在首次创建时,它会自动生成证书库,并要求指定访问证书库的密码。
在创建证书的的时候,需要填写证书的一些信息和证书对应的私钥密码。这些信息包括 CN=xx,OU=xx,O=xx,L=xx,ST=xx,C=xx,它们的意思是:
CN(Common Name名字与姓氏)
OU(Organization Unit组织单位名称)
O(Organization组织名称)
L(Locality城市或区域名称)
ST(State州或省份名称)
C(Country国家名称)
可以采用交互式让工具提示输入以上信息,也可以采用参数
-dname "CN=xx,OU=xx,O=xx,L=xx,ST=xx,C=xx"来自动创建。
例如这条命令:
keytool -genkey -alias testCA -keyalg RSA -keysize 1024 -keystore testCALib -validity 3650
在数字证书库testCALib中创建了一个别名为testCA,使用RSA算法加密的,有效期为3650天的数字证书。
证书生成以后,我们可以使用命名将数字证书导出为一个文件。
keytool -export -alias testCA -file testCA.cer -keystore testALib -rfc
有关keytool的其他用法可以查询keytool的帮助文档。
数字证书生成以后,我们需要使用生成的数字证书给程序包签名,这个是使用jarsigner 工具。例如,如果我们有一个android的程序包calendar.apk.,我们就可以使用刚生成的testCA给改程序包签名。
jarsigner -keystore testCALib calendar.apk testCA.
Android数字证书概述:
Android系统要求每一个安装进系统的应用程序都是经过数字证书签名的,数字证书的私钥则保存在程序开发者的手中。Android将数字证书用来标识应用程序的作者和在应用程序之间建立信任关系,儿不是用来决定最终用户可以安装哪些应用程序。这个数字证书并不需要权威的数字证书签名机构认证,它只是用来让应用程序包自我认证的。
Android数字证书包含以下几个要点:
(1)所有的应用程序都必须有数字证书,Android系统不会安装一个没有数字证书的应用程序
(2)Android程序包使用的数字证书可以是自签名的,不需要一个权威的数字证书机构签名认证
(3)如果要正式发布一个Android ,必须使用一个合适的私钥生成的数字证书来给程序签名,而不能使用adt插件或者ant工具生成的调试证书来发布。
(4)数字证书都是有有效期的,Android只是在应用程序安装的时候才会检查证书的有效期。如果程序已经安装在系统中,即使证书过期也不会影响程序的正常功能。
(5)Android使用标准的java工具 Keytool and Jarsigner 来生成数字证书,并给应用程序包签名。
Android系统不会安装运行任何一款未经数字签名的apk程序,无论是在模拟器上还是在实际的物理设备上。Android的开发工具(ADT插件和Ant)都可以协助开发者给apk程序签名,它们都有两种模式:调试模式(debug mode)和发布模式(release mode)。
在调试模式下,android的开发工具会在每次编译时使用调试用的数字证书给程序签名,开发者无须关心。
当要发布程序时,开发者就需要使用自己的数字证书给apk包签名,可以有两种方法。
(1)在命令行下使用JDK中的和Keytool(用于生成数字证书)和Jarsigner(用于使用数字证书签名)来给apk包签名
(2)使用ADT Export Wizard进行签名(如果没有数字证书可能需要生成数字证书)
签名策略:
同一个开发者的多个程序尽可能使用同一个数字证书,这可以带来以下好处。
(1)有利于程序升级,当新版程序和旧版程序的数字证书相同时,Android系统才会认为这两个程序是同一个程序的不同版本。如果新版程序和旧版程序的数字证书不相同,则Android系统认为他们是不同的程序,并产生冲突,会要求新程序更改包名。
(2)有利于程序的模块化设计和开发。Android系统允许拥有同一个数字签名的程序运行在一个进程中,Android程序会将他们视为同一个程序。所以开发者可以将自己的程序分模块开发,而用户只需要在需要的时候下载适当的模块。
(3)可以通过权限(permission)的方式在多个程序间共享数据和代码。Android提供了基于数字证书的权限赋予机制,应用程序可以和其他的程序共享概功能或者数据给那那些与自己拥有相同数字证书的程序。如果某个权限(permission)的protectionLevel是signature,则这个权限就只能授予那些跟该权限所在的包拥有同一个数字证书的程序。
另一个需要考虑的是Android数字证书的有效期:
(1)数字证书的有效期要包含程序的预计生命周期,一旦数字证书失效,持有改数字证书的程序将不能正常升级。
(2)如果多个程序使用同一个数字证书,则该数字证书的有效期要包含所有程序的预计生命周期。
(3)Android Market强制要求所有应用程序数字证书的有效期要持续到2033年10月22日以后。
理解 Android 上的安全性
利用沙箱、应用程序签名和权限增强应用程序安全性
Android 包括一个应用程序框架、几个应用程序库和一个基于 Dalvik 虚拟机的运行时,所有这些都运行在 Linux® 内核之上。通过利用 Linux 内核的优势,Android 得到了大量操作系统服务,包括进程和内存管理、网络堆栈、驱动程序、硬件抽象层以及与本文主题 —— 安全性 —— 相关的服务。
前提条件要跟随本文,需要具备以下技能和工具:
- 基本了解 Java™ 技术和如何使用 Eclipse(或者您喜欢的 IDE)
- Java Development Kit(需要版本 5 或 6)
- Eclipse(版本 3.4 或 3.5)
- Android SDK 和 ADT 插件
有关下载和设置方面的信息,请参见本文结尾的 参考资料 部分。
Android 使用沙箱的概念来实现应用程序之间的分离和权限,以允许或拒绝一个应用程序访问设备的资源,比如说文件和目录、网络、传感器和 API。为此,Android 使用一些 Linux 实用工具(比如说进程级别的安全性、与应用程序相关的用户和组 ID,以及权限),来实现应用程序被允许执行的操作。
概念上讲,沙箱可以表示为 图 1 所示。
图 1. 两个 Android 应用程序,各自在其自己的基本沙箱或进程上
Android 应用程序运行在它们自己的 Linux 进程上,并被分配一个惟一的用户 ID。默认情况下,运行在基本沙箱进程中的应用程序没有被分配权限,因而防止了此类应用程序访问系统或资源。但是 Android 应用程序可以通过应用程序的 manifest 文件请求权限。
通过做到以下两点,Android 应用程序可以允许其他应用程序访问它们的资源:
- 声明适当的 manifest 权限
- 与其他受信任的应用程序运行在同一进程中,从而共享对其数据和代码的访问
后者演示在 图 2 中。
图 2. 两个 Android 应用程序,运行在同一进程上
不同的应用程序可以运行在相同的进程中。对于此方法,首先必须使用相同的私钥签署这些应用程序,然后必须使用 manifest 文件给它们分配相同的 Linux 用户 ID,这通过用相同的值/名定义 manifest 属性 android:sharedUserId
来做到。
图 3 演示了很多在开发 Android 应用程序时会发现的与安全性相关的用例。
图 3. 编写 Android 应用程序时出现的安全领域
- 应用程序或代码签名是这样一个过程,即生成私有、公共密钥和公共密钥证书,签署和优化应用程序。
- 权限是 Android 平台的一种安全机制,以允许或限制应用程序访问受限的 API 和资源。默认情况下,Android 应用程序没有被授予任何权限,不允许它们访问设备上受保护的 API 或资源,从而保证了它们的安全。权限必须被请求,定义了定制的权限,文件和内容提供者就可以受到保护。确保在运行时检查、执行、授予和撤销权限。
接下来,更加详细地来看一下每个安全领域。
所有 Android 应用程序都必须被签名。应用程序或代码签名是一个这样的过程,即使用私有密钥数字地签署一个给定的应用程序,以便:
- 识别代码的作者
- 检测应用程序是否发生了改变
- 在应用程序之间建立信任
基于这一信任关系,应用程序可以安全地共享代码和数据。
使用相同数字签名签署的两个应用程序可以相互授予权限来访问基于签名的 API,如果它们共享用户 ID,那么也可以运行在同一进程中,从而允许访问对方的代码和数据。
应用程序签名首先是生成一个私有、公共密钥对和一个相关公共密钥证书,简称为公共密钥证书。
构建 Android 应用程序时可以采用调试模式和发布模式:
- 使用 Android 构建工具(命令行和 Eclipse ADT)构建的应用程序是用一个调试私有密钥自动签名的;这些应用程序被称为调试模式应用程序。调试模式应用程序用于测试,不能够发布。注意,未签名的或者使用调试私有密钥签名的应用程序不能够通过 Android Market 发布。
- 您准备发布自己的应用程序时,必须构建一个发布模式的版本,这意味着用私有密钥签署应用程序。
Android 中的代码签名采用一种比其他移动平台中要简单得多的方式。在 Android 上,证书可以是自签名的,这就是说,无需证书授权。这种方法简化了发布过程和相关的成本。
接下来,介绍如何从命令行以及通过使用 Eclipse ADT 手动签署 Android 应用程序。本文中不介绍第三种方法,即使用 Ant。
回想一下,调试模式应用程序是使用调试密钥/证书由构建工具自动签名的。要签署一个发布模式的应用程序,首先必须生成私有、公共密钥对和公共密钥证书。可以手动地或者通过使用 Eclipse ADT 签署应用程序。两种方法中都使用了 Java Developer Kit (JDK) keytool 密钥和证书管理实用工具。
要手动生成私有、公共密钥信息,可以从命令行使用 keytool
,如 清单 1 所示。
清单 1. 使用
keytool
生成私有/公共密钥和证书
keytool -genkey -v -alias <alias_name> -keystore <keystore.name> -keyalg RSA -keysize 2048 -validity <number of days> |
注意:清单 1 假设 JDK 已安装在您的计算机上,并且 JAVA_HOME
路径被正确定义为指向您的 JDK 目录(参见 参考资料,获得下载和设置信息)。
在 清单 1 中,-genkey
表示一个公共、私有密钥对项,以及一个 X.509 v1 自签署的单个元素证书链,其中包含生成的公共密钥。-v
表示冗长模式。-alias
是用于 keystore 项的别名,keystore 存储生成的私有密钥和证书。-keystore
表示使用的密钥仓库的名称。-keyalg
是用来生成密钥对的算法。-keysize
是生成的密钥大小,其中默认大小是 1024,但是推荐大小是 2048。-validity
是有效天数;推荐采用大于 1000 的值。
注意:生成密钥之后,一定要保证密钥的安全。不要共享私有密钥,也不要在命令行或脚本中指定密钥;注意,keytool 和 jarsigner 会提示输入密码。关于这一技巧和其他技巧,请参考 Android Developers 网站的 “Securing Your Private Key”(参见 参考资料 中的链接)。
Keytool
提示您输入名和姓、公司、城市、州、国家,从这些信息生成一个 X.500 Distinguished Name(更多信息请参见参考资料),还要输入保护私有密钥和密钥仓库本身的密码。
对于有效期,请确保使用超出应用程序本身和相关应用程序预期生命期的时期。如果您是在 Android Market 上发布应用程序,那么有效期必须晚于 2033 年 10 月 22 日结束;否则不能上载。此外,拥有长寿命的证书让升级应用程序更为容易。幸运的是,Android Market 强制采用长寿命的证书,以帮助您避免此类问题。
接下来,使用 jarsigner
工具(它是 JDK 的一部分)签署未签名的应用程序:
jarsigner -verbose -keystore <keystore.name> <my_application.apk> <alias_name> |
在上述代码中,-verbose
表示冗长模式,-keystore
表示使用的密钥仓库的名称。接下来是应用程序的名称 (.apk),最后是用于私有密钥的别名。
Jarsigner
提示您输入使用密钥仓库和私有密钥时的密码。
应用程序可以使用不同的密钥进行多次签名,用相同私有密钥签名的应用程序之间可以建立一种信任关系,并且可以运行在同一进程中,共享代码和数据。
签署过程的最后一步是优化应用程序,以便数据边界与文件的开始是内存对齐的,这种技术有助于改善运行时性能和内存利用率。要签署应用程序,可以使用 zipalign
:
zipalign -v 4 your_project_name-unaligned.apk your_project_name.apk |
在前面的代码中,-v
表示冗长输出。数字 4 表示使用四字节对齐(总是使用四字节)。下一个参数是输入已签署应用程序的文件名 (.apk),它必须用您的私有密钥签署。最后一个参数是输出文件名;如果覆盖现有应用程序,则添加一个 -f
。
要验证应用程序已经签署,可以使用 Jarsigner
,这次传递 -verify
标志:
jarsigner -verify -verbose -certs my_application.apk |
在前面的代码中,-verify
表示验证应用程序;-verbose
表示冗长模式;-certs
表示展示创建密钥的 CN 字段,最后一个参数是要验证的 Android 应用程序包的名称。
注意:如果 CN 读入 "Android Debug",那么意味着应用程序是用调试密钥签署的,这表明不能发布;如果您计划在 Android Market 上发布您的应用程序,一定要记得使用私有密钥。
刚才学习了如何手动创建私有、公共密钥,以及签署和优化应用程序。接下来,了解如何使用 Eclipse ADT 自动创建私有、公共密钥,以及签署和优化应用程序。
使用 Eclipse ADT 创建密钥和证书,以及签署和优化应用程序
要使用 Eclipse ADT 生成密钥,必须导出应用程序。有两种方法从 Eclipse 导出应用程序:
- 导出您必须手动签署的应用程序的未签署 版本
- 导出应用程序的已签署 版本,其中所有步骤都由 ADT 为您代劳
您可以导出您必须手动签署的应用程序的未签署版本。就是说,您需要手动运行 keytool(如前所述,是为了生成密钥)和 Jarsigner(为了签署应用程序),并使用 zipalign 工具优化应用程序,跟前面解释的那样。
要使用 ADT 导出应用程序的未签署版本,可以右键单击项目并选择 Android Tools>Export Unsigned Application Package(参见 图 4)。
图 4. 导出未签署的应用程序
选中之后,ADT 提示您选择将未签署应用程序导出到的目录。记住,一旦应用程序被导出,您就必须手动签署和优化应用程序,跟前面介绍的那样。
利用 Eclipse ADT,您可以导出应用程序的已签署版本。使用这种方法,ADT 提示您输入以下内容:
- 使用现有 KeyStore 或者创建新的受保护 KeyStore 所需的信息
- 创建受保护私有密钥所需的信息
- 生成公共密钥证书所需的信息
要导出已签署的应用程序,可以右键单击项目,但是这一次选择菜单项 Android Tools->Export Signed Application Package,如 图 5 所示。
图 5. 导出已签署的应用程序
此时,Export Wizard 执行,如 图 6 所示。
图 6. Export Wizard
在 图 7 中,选择一个现有的密钥仓库(或者创建一个新的)和证书。
图 7. Export Wizard:密钥仓库选择
在 图 8 中,输入信息以创建私有密钥和数字证书。
图 8. Export Wizard:创建私有密钥和数字证书
在 图 9 中,输入目标文件的路径和名称,并验证有效期间。
图 9. 输入目标文件的路径和名称
完成时,您就有了一个发布模式的已签署和已优化的应用程序,您可以发布它。
另外,您也可以使用 Android Manifest 工具调用 Export Wizard,如 图 10 所示。
图 10. 使用 Android Manifest 工具调用 Export Wizard
应用程序签署之后,下一步由您在 manifest 中定义应用程序需要的权限。接下来将描述这一过程。
注意,Android Developer 网站有非常好的关于应用程序签署的文档,当有 Android 平台的新版本可用时,这些文档都会更新(参见 参考资料,了解更多信息)。
权限是一种 Android 平台安全机制,旨在允许或限制应用程序访问受限的 API 和资源。默认情况下,Android 应用程序没有被授予权限,这通过不允许它们访问设备上的受保护 API 或资源,确保了它们的安全。权限在安装期间通过 manifest 文件由应用程序请求,由用户授予或不授予。
Android 定义长长的一系列 manifest 权限,以保护系统或其他应用程序的各个方面。要请求权限,可以在 manifest 文件中声明一个 <user-permission>
属性:
<uses-permission android:name="string" /> |
其中 android:name
指定权限的名称。
要得到所有 Android 定义的 manifest 权限的列表,请参见 Manifest.permisson 页面。清单 2 是一个 manifest 文件的例子,它请求使用 Internet 的权限和写到外部存储器的权限:
清单 2. 声明(请求)权限
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.cenriqueortiz.tutorials.datastore" android:installLocation="auto"> <application : : : </application> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> </manifest> |
应用程序可以定义它们自己的定制权限,以保护应用程序资源。其他应用程序想要访问一个应用程序的受保护资源,就必须通过它们自己的 manifest 文件请求适当的权限。清单 3 展示了一个如何定义权限的例子。
清单 3. 声明定制权限
<permission xmlns:android="http://schemas.android.com/apk/res/android" android:name="com.cenriqueortiz.android.ACCESS_FRIENDS_LIST" android:description="@string/permission_description" android:label="@string/permission_label" android:protectionLevel="normal" > </permission> |
在 清单 3 中,通过指定最少的属性,即 name
、description
、label
和 protectionLevel
,定义了一个定制权限。也可以定义其他属性,但是这里没做介绍。
特别有趣的是 android:protectionLevel
属性,它表示系统向一个请求权限的应用程序授予(或不授予)给定的权限时应该遵循的方法。保护级别有普通 和危险。前者自动授予权限(尽管用户在安装之前总是可以重审),基于签名授予权限(就是说,如果请求权限的应用程序是用同一证书签署的);后者表示权限给予私有数据的访问权,或者具有另一个潜在的负面影响。有关 <permission>
manifest 属性的更多信息,请参见 <permission> 页面(参见 参考资料)。
应用程序可以限制对应用程序及其使用的系统组件(比如 Activity、Service、Content Provider 和 Broadcast Receiver)的访问。通过像 清单 4 中那样定义 android:permission
属性,很容易实现这种限制。这种级别的保护让应用程序允许或限制其他应用程序访问系统资源。
清单 4. 定义一个活动的权限
<activity android:name=".FriendsListActivity" android:label="Friends List"> android:permission="com.cenriqueortiz.android.ACCESS_FRIENDS_LIST" <intent-filter> : : </intent-filter> </activity> |
内容提供者暴露一个公共 URI,用于惟一地识别它们的数据(参见 参考资料)。要保护此内容提供者,当开始时或者从活动返回结果时,调用者可以设置 Intent.FLAG_GRANT_READ_URI_PERMISSION
和 Intent.FLAG_GRANT_WRITE_URI_PERMISSION
,以便授予接收活动权限,以访问特定的数据 URI。
应用程序文件默认是受保护的。文件基于用户 ID 受保护,因而只对所有者应用程序是可访问的(此应用程序具有相同的用户 ID)。正如前面介绍的,共享相同用户 ID(并使用相同数字证书签署)的应用程序运行在相同进程上,因而共享对它们的应用程序的访问。
应用程序可以允许其他应用程序或进程访问它们的文件。这种允许是通过指定适当的 MODE_WORLD_READABLE
和MODE_WORLD_WRITEABLE
操作模式(以便允许对文件的读或写访问)或 MODE_PRIVATE
(以便以私有模式打开文件)而做到的。您可以在创建或打开文件时利用以下方法指定操作模式:
getSharedPreferences(filename, operatingMode)
openFileOutput(filename, operatingMode)
openOrCreateDatabase(filename, operatingMode, SQLiteDatabase.CursorFactory)
Android 提供各种 API 来在运行时检查、执行、授予和撤销权限。这些 API 是 android.content.Context
类的一部分,这个类提供有关应用程序环境的全局信息。例如,假设您想要优雅地处理权限,您可以确定您的应用程序是否被授予了访问 Internet 的权限(参见 确定 5)。
清单 5. 使用运行时
Permission
API 在运行时检查权限
if (context.checkCallingOrSelfPermission(Manifest.permission.INTERNET) != PackageManager.PERMISSION_GRANTED) { // The Application requires permission to access the // Internet"); } else { // OK to access the Internet } |
要了解其他在运行时检查、执行、授予和撤销权限的权限 API,请参考上下文类。
本文介绍了 Android 平台上的安全性,包括沙箱、应用程序签名、应用程序权限,以及文件和内容提供者权限。阅读完这篇介绍性文章之后,您将能够使用 Eclipse 手动创建数字证书,请求应用程序权限,以及允许或不允许应用程序访问文件和内容提供者。此外,您还简要了解了权限运行时 API,这些 API 允许您在运行时检查、执行、授予和撤销权限。
“USB调试”能够实现那些操作
同步应用管理
一旦用户开启“USB调试”设置,相当于用户放弃了对于手机一半的控制权,91手机助手、豌豆荚等工具可以直接获取用户的应用以及通讯录等信息,尽管在未Root的情况下用户可以有选择的控制部分权限的开放,但难保一时点错开放了一些隐私数据。
直接Root手机
刷机精灵基于USB调试的功能
一旦“USB调试”设置开放,PC端的软件可以非常快速的对于支持的手机进行Root操作,对于以娱乐为主的玩家Root是必须的,但更看重安全的用户Root是一件非常有风险的事情,手机一旦root,其最高权限很容易被各种应用随意调用,其安全风险不言而喻。
解锁锁屏密码
一旦手机开启了“USB调试”那么锁屏密码完全形同虚设,一下笔者简单测试了Android4.0.4、Android 4.1.1以及Android 4.2.1的手机锁屏密码解锁操作。
Android 4.0.4
笔者选取了搭载Android 4.0.4的HTC EVO 3D进行锁屏解锁测试。HTC EVO 3D是默认开启“USB调试”设置的手机,任何用户都可以通过91手机助手、豌豆荚或者刷机精灵进行连接配置。
笔者选择91手机助手进行联机,联机之后手机屏幕直接跳过了锁屏界面,并显示主界面。使用Google官方提供的账号解锁方式,在账号同步的设置中绑定自己的Google账号,之后返回锁屏界面输入错误五次之后,系统会自动弹出“忘记密码”选项,按照提示输入已绑定的Google账号,密码即可以轻松清除。
绑定Google账号后输入5次以上错误密码后会显示“忘记图案”
调用USB调试后可轻松跳过锁屏并绑定账号
官方提示USB调试的安全隐患
Android 4.1.1
笔者选取了搭载Android 4.1.1的OPPO Find 5进行锁屏解锁测试。OPPO Find 5默认也是开启“USB调试”,解锁密码过程与Android 4.0.4的EVO 3D非常类似,可以轻松清除解锁密码。
Android 4.2.1
笔者选取了搭载Android 4.2.1的三星 Nexus S进行锁屏解锁测试。手机默认是关闭“USB调试”且隐藏“开发人员选项”选项的,没有Root的情况下很难讲锁屏密码清除,并且91、豌豆荚等工具也不能够链接手机进行操作。
Android 4.2系统默认隐藏USB调试设置
但是一旦用户通过进入开发者模式开启了“USB调试”设置功能,如同上面两个手机一样,清除密码及Root非常容易。(通过连击“关于手机”中的“版本号”可以调出“开发者选项”)
实际上一旦开放了“USB调试”锁屏等安全措施就有可能面临危险,一旦有恶意程序通过应用通过用户的过失操作,就可以获得手机用户的全部信息。
如何保证手机安全
“USB调试”是Android手机安全隐患的一个方面,它为开发者提供了便利,但是对于用户开放该设置将引发一连串的风险。尽管91手机助手、豌豆荚等工具为用户提供帮助,但是更多程序通过这个功能真正掌控了用户的手机。基于以上理由,Google在Android4.2.2中默认关闭了“USB调试”设置,并隐藏了开发者模式,而如果您需要保障手机的相对安全关闭“USB调试”或许能够规避更多的安全风险。
编辑点评:目前,在国内对信息泄露这方面的问题早是司空见惯,乃至成为一公开秘密。虽然已谈不上绝对的信息安全,但仍不希望玩家最终图一时之便而弃危险于不顾,所以说“USB调试”还是慎用为好,安全至上!