- 浏览: 537969 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
landerson:
明显就有要求的嘛
ANDROID轻量级JSON序列化和反序列化[转] -
jimode2013:
很不错,就是需要这个方法
多个UIViewController使用addSubView,第二个 UIViewController 不响应旋转[转] -
w11h22j33:
...
[转]NSMutableArray中的自动释放对象让我郁闷了一整天 -
w11h22j33:
UILabel* label = [[UILabel a ...
Iphone开发 -
w11h22j33:
http://mobile.51cto.com/iphone- ...
获得通讯录中联系人的所有属性[转]
开发 Android 应用程序时,必须处理很多与安全性相关的方面,包括应用程序进程和沙箱、代码和数据共享、通过应用程序签名达到的系统保护,以及权限使用。在您使用样例代码时,突出强调了 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 来做到。
下图演示了很多在开发 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 为您代劳
导出未签署的应用程序
您可以导出您必须手动签署的应用程序的未签署版本。就是说,您需要手动运行 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. 使用运行时 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 允许您在运行时检查、执行、授予和撤销权限。
发表评论
-
干掉你程序中的僵尸代码【转】
2012-12-22 11:05 965随着万圣节越来越流行,我感觉有必要跟大家讨论一下一个 ... -
一个文本框搞定信用卡相关信息的输入[转]
2012-12-22 11:03 1139http://beforweb.com/node/134 ... -
android 开源 OCR 项目 及手写识别[转]
2012-12-11 18:21 57701)一个为Android平台,将识别由手机的相机拍摄的图 ... -
Android通过共享用户ID来实现多Activity进程共享【转】
2012-12-10 14:33 1109http://mypyg.iteye.com/blog/720 ... -
Android应用程序组件Content Provider的启动过程源代码分析【转】
2012-12-05 18:31 1147通过前面的学习,我们知道在Android系统中,Cont ... -
Android 安全机制概述 Permission【转】
2012-12-03 18:07 11741 Android 安全机制概述 Android 是一个权限分 ... -
Android学习笔记之一谁动了我的接口附checkPermission流程(Dean)[转]
2012-12-03 18:06 18126前段时间接到一个有趣的需求!我们实现的某某功能的手机对外提供了 ... -
(JAVA) 使用异或进行简单的密码加密(JAVA实现)[转]
2012-11-12 16:44 1219http://blog.sina.com.cn/s/bl ... -
SL4A 之实现原理解析【转】
2012-10-23 23:52 1285关于SL4A的简介和在Android系统的安装及使用,请参 ... -
百度地图API之根据经纬度查询地址信息(Android)[转]
2012-06-16 00:15 19803http://blog.csdn.net/lyq8479/ar ... -
百度地图的手动定位和自动定位[转]
2012-06-15 23:24 3458http://aokunsang.iteye.com/b ... -
如何编程实现开启或关闭GPS?
2012-06-09 22:14 1132来自 手机应用中最酷的可能就是位置服务相关的了, ... -
Android软键盘的隐藏显示研究[转]
2012-05-25 16:30 1444Android是一个针对触摸屏专门设计的操作系统,当点 ... -
15 个变量和方法命名的最佳实践[转]
2012-02-27 11:44 103115 个变量和方法命名的最佳实践 在每个代码范围内使用足够短 ... -
iPhone Android Web开发(概要)
2012-01-19 15:15 1070一、 前端使用技术 JavaScript、 jQuer ... -
移动 电信 联通 APN cmwap cmnet ctwap ctnet 3gwap uniwap 3gnet uninet设置[转]
2011-11-23 14:35 2781APN(Access Point Name),即“接入 ... -
Android Http CMWAP联网获取实例【转】
2011-10-24 13:24 1403上午的时候原本想通过改变切入点的方式来实现cmwap,但是我们 ... -
监听ListView滚动到最底部【转】
2011-09-13 10:27 5883监听ListView的滚动可以用两个东西: ListV ... -
Android蓝牙开发浅谈【转】
2011-09-07 14:20 1574转自:http://www.eoeandroid.co ... -
修改Android模拟器的HOST
2011-06-03 11:08 4223C:\WINDOWS\system32\drivers ...
相关推荐
理解 Android 上的安全性
综上所述,《深入理解Android 卷III》这本书不仅会从宏观角度讲解Android系统的整体架构,还会深入探讨具体的开发技术和性能优化方法。无论是对于想要深入学习Android内部机制的技术人员,还是希望提高自己开发水平...
在Android软件安全与逆向分析的第五...这一章的内容旨在帮助读者建立对Android应用安全性的全面理解,并掌握逆向分析的基本技能。无论是为了开发更安全的应用,还是为了检测和防御恶意软件,这些知识都将提供宝贵指导。
1. Android系统架构:理解Android系统的层次结构,包括Linux内核、HAL层、系统服务、应用程序框架以及用户界面。 2. Dalvik与ART:探讨Android运行时环境的Dalvik虚拟机和后来的ART(Android RunTime)如何执行应用...
这本书以其深度和全面性,为Android开发者提供了宝贵的洞察力,使得开发者能够深入理解Android系统的运行机制,从而更好地优化应用性能、解决实际问题。 在本书中,你可以学到以下关键知识点: 1. **Android系统...
通过阅读《Android软件安全与逆向分析》,读者不仅可以学习到Android安全的基础知识,还能掌握实战技能,对提高Android应用的安全性具有重要价值。无论是开发者还是安全研究人员,都能从中受益匪浅。
这些书籍是深入理解Android平台安全性的宝贵资源,对于开发者、安全研究人员以及对移动安全有兴趣的个人来说,具有很高的学习价值。 一、Android安全机制解析与应用实践 这本书主要探讨了Android操作系统的基础安全...
13. **安全性**:讨论Android应用的安全性问题,如何防止逆向工程,以及数据加密和隐私保护。 14. **性能优化**:分享性能分析技巧,如何进行代码优化,提高应用的响应速度和电量效率。 15. **单元测试与自动化...
《深入理解Android:WIFI模块 NFC和GPS卷》是一本专为Android开发者和爱好者准备的高级技术指南,旨在帮助读者全面掌握Android系统中无线通信、近场通信和定位服务的关键技术。这本书详细阐述了Android平台下WiFi、...
了解这些基础是理解Android安全问题的关键。作者会深入解析应用程序的生命周期、组件通信方式(如Intent)以及它们如何影响安全。 其次,书中会详细介绍Android应用的逆向工程,包括APK的结构、dex文件格式、Java...
### 深入理解Android之Java Security #### 一、Java Security 背景知识 Java Security 是 Java 平台中的一个重要组成部分,它不仅在软件实现方面有着丰富的内容,而且还涉及一系列规范。从 Java 2 开始,Java ...
《深入理解Android:Telephony原理剖析与最佳实践》是一本专注于Android系统中Telephony模块的专著。Telephony是Android操作系统中的核心组件之一,主要负责处理手机的电话、短信等功能,涉及到了移动通信领域的诸多...
5. **安全性**:讲解Android的安全模型,包括权限管理、数据加密和应用安全实践。 6. **NDK开发**:介绍Native Development Kit,如何使用C/C++进行原生代码开发,以及JNI的使用。 7. **Android测试**:涵盖单元...
通过学习《深入理解Android:卷一》,读者不仅可以掌握Android开发的高级技术,还能培养解决实际问题的能力,从而在Android开发领域更上一层楼。高清版的PDF使得阅读体验更好,便于随时查阅和学习。
Android作为全球最受欢迎的移动操作系统,其安全性至关重要,对于开发者、安全工程师以及对移动安全有兴趣的读者来说,理解其安全架构是必不可少的。 Android安全体系基于多个层次构建,包括硬件层、操作系统层、...
通过对“面向Android安全性的Smali混淆代码分析”的研究,我们不仅能够更加深入地理解Android系统安全性分析的复杂性和挑战,还可以掌握一种有效的代码混淆识别和分析方法。这对于保证Android平台应用的安全性,避免...
《深入理解Android》是邓凡平先生所著的一套关于Android开发的权威指南,分为卷I和卷II,这两部著作对于深入理解Android系统的工作原理和框架设计具有极高的参考价值。书中涵盖了从基础概念到高级技术的广泛内容,...