本文檔向應用開發者介紹如何使用Android提供的安全行特征。
Android是一個特權分離的操作系統,在系統中運行的每個應用程序都有一個區分系統標識(Linux用戶ID和分組ID)。標識的系統部分也被區分不同的身份。因而Linux能夠把應用程序以及系統進行彼此分離。
另外,更細粒度的安全特征是通過“權限”機制來提供的,這種機制強制限制瞭特殊進程所能執行的具體操作,並且給每個URI都設定瞭方位具體數據片段的權限。
安全架構
Android安全架構的核心設計點是,默認的情況下,沒有任何應用程序有權來執行能夠對其他應用程序、操作系統或用戶帶來不利影響的任何操作。包括讀寫用戶的私有數據(如通信錄或e-mail)、讀寫另一個應用程序的文件、執行網絡訪問、保持設備的喚醒狀態等等。
因為Android用沙箱來分離每個應用程序,因此應用程序必須明確要共享的資源和數據。應用程序通過聲明來獲取它們所需要的基本沙箱所不具備的額外能力。應用程序靜態的聲明它們所需要的權限,並且Android系統會在安裝應用程序時,提示應用程序來同意。Android沒有動態(在運行時)授權機制,因為安全的損害會給用戶帶來復雜的用戶體驗。
應用程序沙箱不依賴用於構建應用程序的技術。特別是在Dalvik虛擬機中是沒有安全邊界的,並且任何應用程序都能運行本機代碼。所有類型的應用程序,包括Java、原生的以及混合的應用程序,都以相同的方式被放在沙箱中,它們彼此都有相同的安全程度。
應用程序簽名
所有的Android應用程序(.apk文件)都必須用一個證書來進行簽名,證書的私有鍵被應用的開發者所持有。這個證書標識瞭應用程序的作者,它不需要由證書授權機構來簽署,這是完全允許的,並且通常Android應用都使用自簽名證書。Android中證書的目的是區分應用程序的作者。這樣就允許系統接受或拒絕應用程序訪問簽名級別的權限,以及接受或拒絕應用程序要求獲得與另一個應用程序相同的Linux身份的請求。
用戶ID和文件訪問
在安裝時,Android系統會給每個包分配一個不同的Linux用戶ID。這個身份標識對於設備上處於運行期間的包會保持不變。在不同的設備上,同樣的包可能會有不同的UID,這不重要,重要的是在一個設備上,每個包要有不同的UID。
因為安全是在進程級別上強制發生的,任何兩個包的代碼通常不會運行在同一個進程中,因此它們需要用不同的Linux用戶來運行。能夠在每個包的Androidmanifest.xml文件中的<manifest>標簽中使用sharedUserId屬性,來給它們分配相同的用戶ID。通過這樣做,這些設置瞭相同用戶ID的包會被視為同一個應用程序,並具有相同的權限。要註意的時,為瞭保留安全性,隻有使用瞭相同的簽名的應用程序(並且申請瞭相同的sharedUserId屬性)才會給分配相同的用戶ID。
應用程序存儲的任何數據,都會把應用的用戶ID分配給它,並且通常其他的包不能訪問它。當用getSharedPreferences(String, int)、openFileOutput(String, int)或openOrCreateDatabase(String, int, SQLiteDatabase.CureorFactory)等方法創建一個新的文件時,能夠使用MODE_WORLD_READABLE和(或)MODE_WORLD_WRITEABLE標記來允許其他的包來讀寫這個文件。當設置瞭這些標記時,這個文件依然被創建它的應用程序所擁有,隻是被設置全局的讀寫權限,以便其他應用程序能夠訪問它。
使用權限
一個基本的Android應用程序是沒有權限跟它關聯,這意味著它不能夠做任何給用戶體驗或設備上的數據帶來不利影響的事情,要使用設備上那些受保護的功能,必須在應用程序的AndroidManifest.xml文件中包含一個或多個<uses-permission>標簽,來聲明應用程序需要的權限。
例如,需要監視器接收SMS消息的應用程序,應該指定以下設置:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.app.myapp" >
<uses-permission android:name="android.permission.RECEIVE_SMS" />
…
</manifest>
在應用程序安裝時,應用程序申請的權限會通過Android的包安裝器來授予,包安裝器通過應用程序聲明的權限和(或)跟用戶進行交互來檢查是否應該將對應的權限授予該應用程序。在應用程序運行是,它不會檢查權限。也就是說,要麼在安裝時就給應用程序授予其所申請的權限,使其能夠使用這些權限所限定的功能,要麼不批準其所申請的權限,使其不能使用這些權限所限定的功能,並用戶也不會得到任何提示。
很多時候,由於沒有權限而導致的失敗,會給應用程序拋出一個SecurityException異常。但是並不保證沒有權限的任何地方都會發生這個異常。例如,sendBroadcast(Intent)方法在發送數據時,會檢查每個接受器的權限,這個方法調用返回之後,如果有權限失敗的情況,也不會收到異常。但是,在幾乎所有的場合,權限相關的失敗會打印一個系統級日志(log)。
由Android系統提供的權限能夠在Manifest.permission類中找到。任何應用程序還可以定義和強制實施它自己的權限,因此這個類中列出的不是所有的可能的權限。
在程序的執行過程中,可在很多地方強制實施一個特殊的權限:
1. 在系統調用的時候,阻止應用程序執行某些功能;
2. 在Activity啟動時,阻止其他應用程序的Activity來啟動本應用;
3. 在發送和接收廣播時,控制誰能接收你的廣播或誰能給你發送廣播;
4. 在訪問並操作一個內容提供器時;
5. 綁定或啟動服務的時候。
摘自 FireOfStar的專欄