1、所有的 Android 应用程序(.apk文件)必须用证书进行签名认证,而这个证书的私钥是由开发者保有的。该证书可以用以识别应用程序的作者。该证书也不需要 CA签名认证(注:CA就是一个第三方的证书认证机构,如 verisign等)。Android 应用程序允许而且一般也都是使用 self-signed 证书(即自签名证书)。证书是用于在应用程序之间建立信任关系,而不是用于控制程序是否可以安装。签名影响安全性的最重要的方式是通过决定谁可以进入基于签名的 permisssions,以及谁可以 share 用户 IDs。用户 IDs和文件存取 每一个 Android 应用程序(.apk文件)都会在
2、安装时就分配一个独有的 Linux 用户ID,这就为它建立了一个沙盒,使其不能与其他应用程序进行接触(也不会让其它应用程序接触它)。这个用户 ID会在安装时分配给它,并在该设备上一直保持同一个数值。由于安全性限制措施是发生进程级,所以两个 package中的代码不会运行在同一个进程当中,他们要作为不同的 Linux 用户出现。我们可以通过使用 AndroidManifest.xml 文件中的 manifest 标签中的 sharedUserId 属性,来使不同的 package共用同一个用户 ID。通过这种方式,这两个 package就会被认为是同一个应用程序,拥有同一个用户 ID(实际不一定
3、),并且拥有同样的文件存取权限。注意:为了保持安全,只有当两个应用程序被同一个签名签署的时候(并且请求了同一个 sharedUserId)才会被分配同样的用户 ID.所有存储在应用程序中的数据都会赋予一个属性-该应用程序的用户 ID,这使得其他package无法访问这些数据。当通过这些方法 getSharedPreferences(String,int),openFileOutput(String,int),or openOrCreateDatabase(String,int,SQLiteDatabase.CursorFactory)来创建一个新文件时,你可以通过使用MODE_WORLD_RE
4、ADABLE and/or MODE_WORLD_WRITEABLE 标志位来设置是否允许其他 package来访问读写这个文件。当设置这些标志位时,该文件仍然属于该应用程序,但是它的 global read and/or write 权限已经被设置,使得它对于其他任何应用程序都是可见的。Security and Permissions 安全与权限(三)Using Permissions 使用权限 一个基本的 Android 程序通常是没有任何 permissions 与之关联的,这就是说它不能做任何扰乱用户或破坏数据的勾当。那么为了使用设备被保护的 features,我们就必须在Androi
5、dManifest.xml 添加一个或多个 标签,用以声明你的应用程序需要的 permissions.下面是个例子 For example,an application that needs to monitor incoming SMS messages would specify:Xml 代码 1.3.4.5.6.应用程序安装的时候,应用程序请求的 permissions 是通过 package installer来批准获取的。package installer是通过检查该应用程序的签名和/或用户的交换结果来确定是否给予该程序 request 的权限。在用户使用过程中不会去检查权限,也就是
6、说要么在安装的时候就批准该权限,使其按照设计可以使用该权限;要么就不批准,这样用户也就根本无法使用该 feature,也不会有任何提示告知用户尝试失败。很多时候,一个 permission failure会导致一个 SecurityException 被抛回该应用程序.但是Android 并不保证这种情况会处处发生。例如,当数据被 deliver到每一个 receiver的时候,sendBroadcast(Intent)方法会去检查 permissions,在这个方法调用返回之后,你也不会收到任何 exception。几乎绝大多数情况,一个 permission failure都会打印到 lo
7、g当中。Android 系统定义的权限可以在 Manifest.permission 中找到。任何一个程序都可以定义并强制执行自己独有的 permissions,因此 Manifest.permission 中定义的 permissions 并不是一个完整的列表(即有肯能有自定义的 permissions)。A particular permission may be enforced at a number of places during your programs operation:一个特定的 permission 可能会在程序操作的很多地方都被强制实施:At the time of
8、a call into the system,to prevent an application from executing certain functions.当系统有来电的时候,用以阻止程序执行其它功能。When starting an activity,to prevent applications from launching activities of other applications.当启动一个 activity的时候,会阻止应用程序启动其它应用的 Acitivity。Both sending and receiving broadcasts,to control who c
9、an receive your broadcast or who can send a broadcast to you.在发送和接收广播的时候,去控制谁可以接收你的广播或谁可以发送广播给你。When accessing and operating on a content provider.当进入并操作一个 content provider的时候 Binding or starting a service.当绑定或开始一个 service的时候 为了实现你自己的 permissions,你必须首先在 AndroidManifest.xml文件中声明该permissions.通常我们通过使用一
10、到多个 tag来进行声明。下面例子说明了一个应用程序它想控制谁才可以启动它的 Activity:Java代码 1.3.4.9.10.这里属性是需要声明的(通常系统自有的 permission 都会有它对应的protection level,而我们自己定义的 permission 一般都需要定义 protecdtion level,若不去定义,则默认为 normal)。通过声明该属性,我们就可以告知系统如何去通告用户以及通告哪些内容,或者告知系统谁才可以拥有该 permission。具体请参看链接的文档。这我多说两句啊,这个 protectionLevel 分四个等级,分别是 Normal,Da
11、ngerous,Signature,SignatureOrSystem,越往后安全等级越高。这个属性是可选项,只是用于帮助系统显示 permissions 给用户(实际是告知系统该 permission 是属于哪个 permission group的)。你通常会选择使用标准的 system group来设定该属性,或者用你自己定义的 group(更为罕见)。通常使用一个已经存在的 group会更合适,因为这样 UI显示的时候会更简单。需要注意的是 label 和 description 都是需要为 permission 提供的。这些都是字符串资源,当用户去看 permission 列表(and
12、roid:label)或者某个 permission 的详细信息(android:description)时,这些字符串资源就可以显示给用户。label 应当尽量简短,之需要告知用户该 permission 是在保护什么功能就行。而 description 可以用于具体描述获取该 permission 的程序可以做哪些事情,实际上让用户可以知道如果他们同意程序获取该权限的话,该程序可以做什么。我们通常用两句话来描述 permission,第一句描述该permission,第二句警告用户如果批准该权限会可能有什么不好的事情发生。下面是一个描述 CALL_PHONE permission 的 la
13、bel 和 description 的例子:Xml 代码 1.directly call phone numbers 2.Allows the application to call 3.phone numbers without your intervention.Malicious applications may 4.cause unexpected calls on your phone bill.Note that this does not 5.allow the application to call emergency numbers.你可以通过 shell 指令 adb sh
14、ell pm list permissions 来查看目前系统已有的 permissions.特别的,-s选项会以一种用户会看到的格式一样的格式来显示这些 permissions.Security and Permissions 安全与权限(五)用于限制进入系统或应用程序的 Components 的高层 permissions 可以再AndroidManifest.xml 中实现.所有这些都可以通过在相应的 component 中包含 android:permission 属性,命名该 permission 以使其被用以控制进入的权限。Activity permissions 限制了谁才可以启
15、动相应的 activity.permission 会在Context.startActivity()和 Activity.startActivityForResult()的时候进行检查。如果 caller没有所需的权限,则会抛出一个 SecurityException。Service permissions 用于限制谁才可以 start 或 bind 该 service。在 Context.startService(),Context.stopService()和 Context.bindService()调用的时候会进行权限检查。BroadcastReceiver permissions 用
16、于限制谁才可以向该 receiver发送广播。权限检查会在Context.sendBroadcast()返回时进行,由系统去发送已经提交的广播给相应的Receiver。最终,一个 permission failure不会再返回给 Caller一个 exception;它只是不会去 deliver该 Intent 而已。同样地,Context.registerReceiver()也可以有自己 permission用于限制谁才可以向一个在程序中注册的 receiver发送广播。另一种方式是,一个permission 也可以提供给 Context.sendBroadcast()用以限制哪一个 Bro
17、adcastReceiver 才可以接收该广播。ContentProvider permission 用于限制谁才可以访问 ContentProvider提供的数据。(Content providers 有一套而外的安全机制叫做 URI permissions,这些在稍后讨论)不同于其它的 Components,这里有两种不同的 permission 属性可以设置:android:readPermission 用于限制谁可以读取 provider中的数据,而 android:writePermission 用于限制谁才可以向 provider中写入数据。需要注意的是如果provider既被 r
18、ead permis 保护,也被 write permission 保护的话,如果这时只有 write permission 并不意味着你就可以读取 provider 中的数据了。当你第一次获取 provider的时候就要进行权限检查(如果你没有任何 permission,则会抛出 SecurityException),并且这时你对 provider执行了某些操作。当使用 ContentResolver.query()时需要读权限,而当使用 ContentResolver.insert(),ContentResolver.update(),ContentResolver.delete()时需要
19、写权限。在所有这些情况下,没有所需的 permission 将会导致 SecurityException 被抛出。除了之前说过的 Permission(用于限制谁才可以发送广播给相应的broadcastReceiver),你还可以在发送广播的时候指定一个 permission。在调用Context.sendBroadcast()的时候使用一个 permission string,你就可以要求 receiver的宿主程序必须有相应的 permission。值得注意的是 Receiver 和 broadcaster都可以要求 permission。当这种情况发生时,这两种 permission 检
20、查都需要通过后才会将相应的 intent 发送给相关的目的地。Security and Permissions 安全与权限(七)|Security and Permissions 安全与权限(五)在调用 service的过程中可以设置任意的 fine-grained permissions(这里我理解的是更为细化的权限)。这是通过 Context.checkCallingPermission()方法来完成的。呼叫的时候使用一个想得到的 permission string,并且当该权限获批的时候可以返回给呼叫方一个Integer(没有获批也会返回一个 Integer)。需要注意的是这种情况只能发
21、生在来自另一个进程的呼叫,通常是一个 service发布的 IDL接口或者是其他方式提供给其他的进程。Android 提供了很多其他的方式用于检查 permissions。如果你有另一个进程的 pid,你就可以通过 context method Context.checkPermission(String,int,int)去针对那个 pid 去检查 permission。如果你有另一个应用程序的 package name,你可以直接用PackageManager method PackageManager.checkPermission(String,String)来确定该package是否已
22、经拥有了相应的权限。到目前为止我们讨论的标准的 permission 系统对于 content provider来说是不够的。一个 content provider可能想保护它的读写权限,而同时与它对应的直属客户端也需要将特定的 URI传递给其它应用程序,以便其它应用程序对该 URI进行操作。一个典型的例子就是邮件程序处理带有附件的邮件。进入邮件需要使用 permission 来保护,因为这些是敏感的用户数据。然而,如果有一个指向图片附件的 URI需要传递给图片浏览器,那个图片浏览器是不会有访问附件的权利的,因为他不可能拥有所有的邮件的访问权限。针对这个问题的解决方案就是 per-URI pe
23、rmission:当启动一个 activity或者给一个activity返回结果的时候,呼叫方可以设置Intent.FLAG_GRANT_READ_URI_PERMISSION 和/或 Intent.FLAG_GRANT_WRITE_URI_PERMISSION.这会使接收该 intent 的 activity获取到进入该 Intent 指定的 URI的权限,而不论它是否有权限进入该 intent 对应的 content provider。这种机制允许一个通常的 capability-style模型,这种模型是以用户交互(如打开一个附件,从列表中选择一个联系人)为驱动,特别获取更细粒化的权限。这是一种减少不必要权限的重要方式,这种方式主要针对的就是那些和程序的行为直接相关的权限。这些 URI permission 的获取需要 content provider(包含那些 URI)的配合。强烈推荐在content provider中提供这种能力,并通过 android:grantUriPermissions 或者 标签来声明支持。更多的信息可以参考 Context.grantUriPermission(),Context.revokeUriPermission(),and Context.checkUriPermission()methods.
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1