自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

[IBM DW] 理解 Android 上的安全性

移動開發(fā) Android

開發(fā) Android 應(yīng)用程序時,必須處理很多與安全性相關(guān)的方面,包括應(yīng)用程序進(jìn)程和沙箱、代碼和數(shù)據(jù)共享、通過應(yīng)用程序簽名達(dá)到的系統(tǒng)保護(hù),以及權(quán)限使用。在您使用樣例代碼時,突出強(qiáng)調(diào)了 Android 應(yīng)用程序開發(fā)中的這些安全方面。

Android 包括一個應(yīng)用程序框架、幾個應(yīng)用程序庫和一個基于 Dalvik 虛擬機(jī)的運(yùn)行時,所有這些都運(yùn)行在 Linux® 內(nèi)核之上。通過利用 Linux 內(nèi)核的優(yōu)勢,Android 得到了大量操作系統(tǒng)服務(wù),包括進(jìn)程和內(nèi)存管理、網(wǎng)絡(luò)堆棧、驅(qū)動程序、硬件抽象層以及與本文主題 —— 安全性 —— 相關(guān)的服務(wù)。

前提條件

要跟隨本文,需要具備以下技能和工具:

  • 基本了解 Java™ 技術(shù)和如何使用 Eclipse(或者您喜歡的 IDE)
  • Java Development Kit(需要版本 5 或 6)
  • Eclipse(版本 3.4 或 3.5)
  • Android SDK 和 ADT 插件

Android 使用沙箱的概念來實(shí)現(xiàn)應(yīng)用程序之間的分離和權(quán)限,以允許或拒絕一個應(yīng)用程序訪問設(shè)備的資源,比如說文件和目錄、網(wǎng)絡(luò)、傳感器和 API。為此,Android 使用一些 Linux 實(shí)用工具(比如說進(jìn)程級別的安全性、與應(yīng)用程序相關(guān)的用戶和組 ID,以及權(quán)限),來實(shí)現(xiàn)應(yīng)用程序被允許執(zhí)行的操作。

概念上講,沙箱可以表示為 圖 1 所示。


圖 1. 兩個 Android 應(yīng)用程序,各自在其自己的基本沙箱或進(jìn)程上
圖:兩個 Android 應(yīng)用程序,各自在其自己的基本沙箱或進(jìn)程上(具有不同的用戶 ID)

Android 應(yīng)用程序運(yùn)行在它們自己的 Linux 進(jìn)程上,并被分配一個惟一的用戶 ID。默認(rèn)情況下,運(yùn)行在基本沙箱進(jìn)程中的應(yīng)用程序沒有被分配權(quán)限,因而防止了此類應(yīng)用程序訪問系統(tǒng)或資源。但是 Android 應(yīng)用程序可以通過應(yīng)用程序的 manifest 文件請求權(quán)限。

通過做到以下兩點(diǎn),Android 應(yīng)用程序可以允許其他應(yīng)用程序訪問它們的資源:

  • 聲明適當(dāng)?shù)?manifest 權(quán)限
  • 與其他受信任的應(yīng)用程序運(yùn)行在同一進(jìn)程中,從而共享對其數(shù)據(jù)和代碼的訪問

后者演示在 圖 2 中。


圖 2. 兩個 Android 應(yīng)用程序,運(yùn)行在同一進(jìn)程上
圖:兩個 Android 應(yīng)用程序,運(yùn)行在同一進(jìn)程上(具有相同的數(shù)字簽名和相同的 Linux 用戶 ID)

不同的應(yīng)用程序可以運(yùn)行在相同的進(jìn)程中。對于此方法,首先必須使用相同的私鑰簽署這些應(yīng)用程序,然后必須使用 manifest 文件給它們分配相同的 Linux 用戶 ID,這通過用相同的值/名定義 manifest 屬性 android:sharedUserId 來做到。

下圖演示了很多在開發(fā) Android 應(yīng)用程序時會發(fā)現(xiàn)的與安全性相關(guān)的用例。 
圖 3. 編寫 Android 應(yīng)用程序時出現(xiàn)的安全領(lǐng)域
圖:編寫 Android 應(yīng)用程序時出現(xiàn)的安全領(lǐng)域

  • 應(yīng)用程序或代碼簽名是這樣一個過程,即生成私有、公共密鑰和公共密鑰證書,簽署和優(yōu)化應(yīng)用程序。
  • 權(quán)限是 Android 平臺的一種安全機(jī)制,以允許或限制應(yīng)用程序訪問受限的 API 和資源。默認(rèn)情況下,Android 應(yīng)用程序沒有被授予任何權(quán)限,不允許它們訪問設(shè)備上受保護(hù)的 API 或資源,從而保證了它們的安全。權(quán)限必須被請求,定義了定制的權(quán)限,文件和內(nèi)容提供者就可以受到保護(hù)。確保在運(yùn)行時檢查、執(zhí)行、授予和撤銷權(quán)限。

接下來,更加詳細(xì)地來看一下每個安全領(lǐng)域。

所有 Android 應(yīng)用程序都必須被簽名。應(yīng)用程序或代碼簽名是一個這樣的過程,即使用私有密鑰數(shù)字地簽署一個給定的應(yīng)用程序,以便:

  • 識別代碼的作者
  • 檢測應(yīng)用程序是否發(fā)生了改變
  • 在應(yīng)用程序之間建立信任

基于這一信任關(guān)系,應(yīng)用程序可以安全地共享代碼和數(shù)據(jù)。

使用相同數(shù)字簽名簽署的兩個應(yīng)用程序可以相互授予權(quán)限來訪問基于簽名的 API,如果它們共享用戶 ID,那么也可以運(yùn)行在同一進(jìn)程中,從而允許訪問對方的代碼和數(shù)據(jù)。

應(yīng)用程序簽名首先是生成一個私有、公共密鑰對和一個相關(guān)公共密鑰證書,簡稱為公共密鑰證書。

構(gòu)建 Android 應(yīng)用程序時可以采用調(diào)試模式和發(fā)布模式:

  • 使用 Android 構(gòu)建工具(命令行和 Eclipse ADT)構(gòu)建的應(yīng)用程序是用一個調(diào)試私有密鑰自動簽名的;這些應(yīng)用程序被稱為調(diào)試模式應(yīng)用程序。調(diào)試模式應(yīng)用程序用于測試,不能夠發(fā)布。注意,未簽名的或 者使用調(diào)試私有密鑰簽名的應(yīng)用程序不能夠通過 Android Market 發(fā)布。
  • 您準(zhǔn)備發(fā)布自己的應(yīng)用程序時,必須構(gòu)建一個發(fā)布模式的版本,這意味著用私有密鑰簽署應(yīng)用程序。

Android 中的代碼簽名采用一種比其他移動平臺中要簡單得多的方式。在 Android 上,證書可以是自簽名的,這就是說,無需證書授權(quán)。這種方法簡化了發(fā)布過程和相關(guān)的成本。

接下來,介紹如何從命令行以及通過使用 Eclipse ADT 手動簽署 Android 應(yīng)用程序。本文中不介紹第三種方法,即使用 Ant。

手動創(chuàng)建私有、公共密鑰和公共密鑰證書

回想一下,調(diào)試模式應(yīng)用程序是使用調(diào)試密鑰/證書由構(gòu)建工具自動簽名的。要簽署一個發(fā)布模式的應(yīng)用程序,首先必須生成私有、公共密鑰對和公共 密鑰證書??梢允謩拥鼗蛘咄ㄟ^使用 Eclipse ADT 簽署應(yīng)用程序。兩種方法中都使用了 Java Developer Kit (JDK) keytool 密鑰和證書管理實(shí)用工具。

要手動生成私有、公共密鑰信息,可以從命令行使用 keytool,如 清單 1 所示。


清單 1. 使用 keytool 生成私有/公共密鑰和證書

				
keytool -genkey -v -alias <alias_name> -keystore <keystore.name>
-keyalg RSA -keysize 2048 -validity <number of days>

注意:清單 1 假設(shè) JDK 已安裝在您的計算機(jī)上,并且 JAVA_HOME 路徑被正確定義為指向您的 JDK 目錄(參見 參考資料,獲得下載和設(shè)置信息)。

在 清單 1 中,-genkey 表示一個公共、私有密鑰對項(xiàng),以及一個 X.509 v1 自簽署的單個元素證書鏈,其中包含生成的公共密鑰。-v 表示冗長模式。-alias 是用于 keystore 項(xiàng)的別名,keystore 存儲生成的私有密鑰和證書。-keystore 表示使用的密鑰倉庫的名稱。-keyalg 是用來生成密鑰對的算法。-keysize 是生成的密鑰大小,其中默認(rèn)大小是 1024,但是推薦大小是 2048。-validity 是有效天數(shù);推薦采用大于 1000 的值。

注意:生成密鑰之后,一定要保證密鑰的安全。不要共享私有密鑰,也不要在命令行或腳本中指定密鑰;注 意,keytool 和 jarsigner 會提示輸入密碼。關(guān)于這一技巧和其他技巧,請參考 Android Developers 網(wǎng)站的 “Securing Your Private Key”。

Keytool 提示您輸入名和姓、公司、城市、州、國家,從這些信息生成一個 X.500 Distinguished Name,還要輸入保護(hù)私有密鑰和密鑰倉庫本身的密碼。

對于有效期,請確保使用超出應(yīng)用程序本身和相關(guān)應(yīng)用程序預(yù)期生命期的時期。如果您是在 Android Market 上發(fā)布應(yīng)用程序,那么有效期必須晚于 2033 年 10 月 22 日結(jié)束;否則不能上載。此外,擁有長壽命的證書讓升級應(yīng)用程序更為容易。幸運(yùn)的是,Android Market 強(qiáng)制采用長壽命的證書,以幫助您避免此類問題。

手動簽署應(yīng)用程序

接下來,使用 jarsigner 工具(它是 JDK 的一部分)簽署未簽名的應(yīng)用程序:

jarsigner -verbose -keystore <keystore.name> <my_application.apk> <alias_name>

在上述代碼中,-verbose 表示冗長模式,-keystore 表示使用的密鑰倉庫的名稱。接下來是應(yīng)用程序的名稱 (.apk),最后是用于私有密鑰的別名。

Jarsigner 提示您輸入使用密鑰倉庫和私有密鑰時的密碼。

應(yīng)用程序可以使用不同的密鑰進(jìn)行多次簽名,用相同私有密鑰簽名的應(yīng)用程序之間可以建立一種信任關(guān)系,并且可以運(yùn)行在同一進(jìn)程中,共享代碼和數(shù)據(jù)。

手動優(yōu)化應(yīng)用程序

簽署過程的最后一步是優(yōu)化應(yīng)用程序,以便數(shù)據(jù)邊界與文件的開始是內(nèi)存對齊的,這種技術(shù)有助于改善運(yùn)行時性能和內(nèi)存利用率。要簽署應(yīng)用程序,可以使用 zipalign:

zipalign -v 4 your_project_name-unaligned.apk your_project_name.apk

 

在前面的代碼中,-v 表示冗長輸出。數(shù)字 4 表示使用四字節(jié)對齊(總是使用四字節(jié))。下一個參數(shù)是輸入已簽署應(yīng)用程序的文件名 (.apk),它必須用您的私有密鑰簽署。最后一個參數(shù)是輸出文件名;如果覆蓋現(xiàn)有應(yīng)用程序,則添加一個 -f。

手動驗(yàn)證應(yīng)用程序已經(jīng)簽署

要驗(yàn)證應(yīng)用程序已經(jīng)簽署,可以使用 Jarsigner,這次傳遞 -verify 標(biāo)志:

jarsigner -verify -verbose -certs my_application.apk

在前面的代碼中,-verify 表示驗(yàn)證應(yīng)用程序;-verbose 表示冗長模式;-certs 表示展示創(chuàng)建密鑰的 CN 字段,最后一個參數(shù)是要驗(yàn)證的 Android 應(yīng)用程序包的名稱。

注意:如果 CN 讀入 "Android Debug",那么意味著應(yīng)用程序是用調(diào)試密鑰簽署的,這表明不能發(fā)布;如果您計劃在 Android Market 上發(fā)布您的應(yīng)用程序,一定要記得使用私有密鑰。

剛才學(xué)習(xí)了如何手動創(chuàng)建私有、公共密鑰,以及簽署和優(yōu)化應(yīng)用程序。接下來,了解如何使用 Eclipse ADT 自動創(chuàng)建私有、公共密鑰,以及簽署和優(yōu)化應(yīng)用程序。

要使用 Eclipse ADT 生成密鑰,必須導(dǎo)出應(yīng)用程序。有兩種方法從 Eclipse 導(dǎo)出應(yīng)用程序:

  • 導(dǎo)出您必須手動簽署的應(yīng)用程序的未簽署 版本
  • 導(dǎo)出應(yīng)用程序的已簽署 版本,其中所有步驟都由 ADT 為您代勞

導(dǎo)出未簽署的應(yīng)用程序

您可以導(dǎo)出您必須手動簽署的應(yīng)用程序的未簽署版本。就是說,您需要手動運(yùn)行 keytool(如前所述,是為了生成密鑰)和 Jarsigner(為了簽署應(yīng)用程序),并使用 zipalign 工具優(yōu)化應(yīng)用程序,跟前面解釋的那樣。

要使用 ADT 導(dǎo)出應(yīng)用程序的未簽署版本,可以右鍵單擊項(xiàng)目并選擇 Android Tools>Export Unsigned Application Package(參見 圖 4)。


圖 4. 導(dǎo)出未簽署的應(yīng)用程序
導(dǎo)出未簽署的應(yīng)用程序的屏幕截圖

選中之后,ADT 提示您選擇將未簽署應(yīng)用程序?qū)С龅降哪夸?。記住,一旦?yīng)用程序被導(dǎo)出,您就必須手動簽署和優(yōu)化應(yīng)用程序,跟前面介紹的那樣。

導(dǎo)出已簽署的應(yīng)用程序

利用 Eclipse ADT,您可以導(dǎo)出應(yīng)用程序的已簽署版本。使用這種方法,ADT 提示您輸入以下內(nèi)容:

  • 使用現(xiàn)有 KeyStore 或者創(chuàng)建新的受保護(hù) KeyStore 所需的信息
  • 創(chuàng)建受保護(hù)私有密鑰所需的信息
  • 生成公共密鑰證書所需的信息

要導(dǎo)出已簽署的應(yīng)用程序,可以右鍵單擊項(xiàng)目,但是這一次選擇菜單項(xiàng) Android Tools->Export Signed Application Package,如 圖 5 所示。


圖 5. 導(dǎo)出已簽署的應(yīng)用程序
導(dǎo)出已簽署的應(yīng)用程序的屏幕截圖

此時,Export Wizard 執(zhí)行,如 圖 6 所示。


圖 6. Export Wizard
Export Wizard 的屏幕截圖

在 圖 7 中,選擇一個現(xiàn)有的密鑰倉庫(或者創(chuàng)建一個新的)和證書。


圖 7. Export Wizard:密鑰倉庫選擇
Export Wizard:密鑰倉庫選擇的屏幕截圖

在 圖 8 中,輸入信息以創(chuàng)建私有密鑰和數(shù)字證書。


圖 8. Export Wizard:創(chuàng)建私有密鑰和數(shù)字證書
Export Wizard:創(chuàng)建私有密鑰和數(shù)字證書的屏幕截圖

在 圖 9 中,輸入目標(biāo)文件的路徑和名稱,并驗(yàn)證有效期間。


圖 9. 輸入目標(biāo)文件的路徑和名稱
輸入目標(biāo)文件的路徑和名稱的屏幕截圖

完成時,您就有了一個發(fā)布模式的已簽署和已優(yōu)化的應(yīng)用程序,您可以發(fā)布它。

另外,您也可以使用 Android Manifest 工具調(diào)用 Export Wizard,如 圖 10 所示。


圖 10. 使用 Android Manifest 工具調(diào)用 Export Wizard
使用 Android Manifest 工具調(diào)用 Export Wizard 的屏幕截圖

應(yīng)用程序簽署之后,下一步由您在 manifest 中定義應(yīng)用程序需要的權(quán)限。接下來將描述這一過程。

注意,Android Developer 網(wǎng)站有非常好的關(guān)于應(yīng)用程序簽署的文檔,當(dāng)有 Android 平臺的新版本可用時,這些文檔都會更新。

權(quán)限是一種 Android 平臺安全機(jī)制,旨在允許或限制應(yīng)用程序訪問受限的 API 和資源。默認(rèn)情況下,Android 應(yīng)用程序沒有被授予權(quán)限,這通過不允許它們訪問設(shè)備上的受保護(hù) API 或資源,確保了它們的安全。權(quán)限在安裝期間通過 manifest 文件由應(yīng)用程序請求,由用戶授予或不授予。

Android 定義長長的一系列 manifest 權(quán)限,以保護(hù)系統(tǒng)或其他應(yīng)用程序的各個方面。要請求權(quán)限,可以在 manifest 文件中聲明一個 <user-permission> 屬性:

<uses-permission android:name="string" />

 

其中 android:name 指定權(quán)限的名稱。

要得到所有 Android 定義的 manifest 權(quán)限的列表,請參見 Manifest.permisson 頁面。清單 2 是一個 manifest 文件的例子,它請求使用 Internet 的權(quán)限和寫到外部存儲器的權(quán)限:


清單 2. 聲明(請求)權(quán)限

				
<?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>

 

應(yīng)用程序可以定義它們自己的定制權(quán)限,以保護(hù)應(yīng)用程序資源。其他應(yīng)用程序想要訪問一個應(yīng)用程序的受保護(hù)資源,就必須通過它們自己的 manifest 文件請求適當(dāng)?shù)臋?quán)限。清單 3 展示了一個如何定義權(quán)限的例子。


清單 3. 聲明定制權(quán)限

				
<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,定義了一個定制權(quán)限。也可以定義其他屬性,但是這里沒做介紹。

特別有趣的是 android:protectionLevel 屬性,它表示系統(tǒng)向一個請求權(quán)限的應(yīng)用程序授予(或不授予)給定的權(quán)限時應(yīng)該遵循的方法。保護(hù)級別有普通 和危險。前者自動授予權(quán)限(盡管用戶在安裝之前總是可以重審),基于簽名授予權(quán)限(就是說,如果請求權(quán)限的應(yīng)用程序是用同一證書簽署的);后者表示權(quán)限給予私有數(shù)據(jù)的訪問權(quán),或者具有另一個潛在的負(fù)面影響。有關(guān) <permission>manifest 屬性的更多信息,請參見 <permission> 頁面。

應(yīng)用程序可以限制對應(yīng)用程序及其使用的系統(tǒng)組件(比如 Activity、Service、Content Provider 和 Broadcast Receiver)的訪問。通過像 清單 4 中那樣定義 android:permission 屬性,很容易實(shí)現(xiàn)這種限制。這種級別的保護(hù)讓應(yīng)用程序允許或限制其他應(yīng)用程序訪問系統(tǒng)資源。

清單 4. 定義一個活動的權(quán)限

<activity 
android:name=".FriendsListActivity"
android:label="Friends List">
android:permission="com.cenriqueortiz.android.ACCESS_FRIENDS_LIST"
<intent-filter>
:
:
</intent-filter>
</activity>

 

內(nèi)容提供者暴露一個公共 URI,用于惟一地識別它們的數(shù)據(jù)。要保護(hù)此內(nèi)容提供者,當(dāng)開始時或者從活動返回結(jié)果時,調(diào)用者可以設(shè)置 Intent.FLAG_GRANT_READ_URI_PERMISSION 和Intent.FLAG_GRANT_WRITE_URI_PERMISSION,以便授予接收活動權(quán)限,以訪問特定的數(shù)據(jù) URI。

應(yīng)用程序文件默認(rèn)是受保護(hù)的。文件基于用戶 ID 受保護(hù),因而只對所有者應(yīng)用程序是可訪問的(此應(yīng)用程序具有相同的用戶 ID)。正如前面介紹的,共享相同用戶 ID(并使用相同數(shù)字證書簽署)的應(yīng)用程序運(yùn)行在相同進(jìn)程上,因而共享對它們的應(yīng)用程序的訪問。

應(yīng)用程序可以允許其他應(yīng)用程序或進(jìn)程訪問它們的文件。這種允許是通過指定適當(dāng)?shù)腗ODE_WORLD_READABLE 和 MODE_WORLD_WRITEABLE 操作模式(以便允許對文件的讀或?qū)懺L問)或MODE_PRIVATE(以便以私有模式打開文件)而做到的。您可以在創(chuàng)建或打開文件時利用以下方法指定操作模式:

  • getSharedPreferences(filename, operatingMode)
  • openFileOutput(filename, operatingMode)
  • openOrCreateDatabase(filename, operatingMode, SQLiteDatabase.CursorFactory)

Android 提供各種 API 來在運(yùn)行時檢查、執(zhí)行、授予和撤銷權(quán)限。這些 API 是android.content.Context 類的一部分,這個類提供有關(guān)應(yīng)用程序環(huán)境的全局信息。例如,假設(shè)您想要優(yōu)雅地處理權(quán)限,您可以確定您的應(yīng)用程序是否被授予了訪問 Internet 的權(quán)限。

清單 5. 使用運(yùn)行時 Permission API 在運(yùn)行時檢查權(quán)限

if (context.checkCallingOrSelfPermission(Manifest.permission.INTERNET)
!= PackageManager.PERMISSION_GRANTED) {
// The Application requires permission to access the
// Internet");
} else {
// OK to access the Internet
}

要了解其他在運(yùn)行時檢查、執(zhí)行、授予和撤銷權(quán)限的權(quán)限 API,請參考上下文類。

本文介紹了 Android 平臺上的安全性,包括沙箱、應(yīng)用程序簽名、應(yīng)用程序權(quán)限,以及文件和內(nèi)容提供者權(quán)限。閱讀完這篇介紹性文章之后,您將能夠使用 Eclipse 手動創(chuàng)建數(shù)字證書,請求應(yīng)用程序權(quán)限,以及允許或不允許應(yīng)用程序訪問文件和內(nèi)容提供者。此外,您還簡要了解了權(quán)限運(yùn)行時 API,這些 API 允許您在運(yùn)行時檢查、執(zhí)行、授予和撤銷權(quán)限。

責(zé)任編輯:冰凝兒
相關(guān)推薦

2017-07-27 19:35:34

2012-08-05 16:57:13

2009-11-30 09:41:38

2011-06-30 11:04:05

JTS

2016-07-05 10:50:44

2010-02-06 10:26:55

Android進(jìn)程

2017-12-29 15:16:28

2015-04-20 15:26:12

2009-07-21 17:22:05

2018-10-18 05:29:04

物聯(lián)網(wǎng)設(shè)備物聯(lián)網(wǎng)安全IOT

2011-03-22 13:50:57

云計算

2012-04-05 09:52:21

開源軟件Linux

2013-04-18 11:48:59

2013-01-15 10:12:39

云存儲云安全

2020-01-18 08:49:17

目錄安全.ssh木馬

2010-04-14 17:19:51

Oracle數(shù)據(jù)庫

2021-10-19 06:05:20

網(wǎng)站安全網(wǎng)絡(luò)威脅網(wǎng)絡(luò)攻擊

2013-01-11 14:00:18

云存儲云計算云安全

2021-10-31 16:10:50

公有云安全性IT

2016-06-12 11:53:27

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號