如何使用「signapk.jar」對「APK」進行簽章

Android:ATV

RICK
Nov 2, 2020

目的

了解如何使用「signapk.jar「對「APK」進行簽章。

概論

在系統廠開發「系統級應用程式」時,與一般「APPs」的開發並不相同,在系統級應用的開發過程中,我們常會需要擁有更大的權限,如常駐的背景服務,以及使用所謂的「非 SDK 接口」,像是「System API」…等。

常見的方式有兩種,一種是編寫「.mk」,將其中「LOCAL_CERTIFICATE」屬性設為「platform」,如下:

而另外一種就是藉由「signapk.jar」來進行系統簽名。

正文

共享系統的「UID」

在開發「系統應用」的過程,若要使用「系統級」的權限,那我們就會在「AndroidManifest」中的「manifest」標籤下加入「sharedUserId」屬性,並將值定義為「android.uid.system」,如下:

關於「sharedUserId」,簡單的說,就是共享「User Id」,並以此來獲得相對應的權限,如下:

由於其牽扯到「Linux OS」對於權限的管理機制,故筆者不打算在此詳述,此外,因為安全性的原因,該標籤也將在「API 29」被棄用。

而要加入的描述符如下:

android:sharedUserId="android.uid.system"

其意義為,我們要讓目前的應用程式共享「系統」的「UID」。

「APK」的「數位簽章機制」

在加入該描述後,若我們像以往直接編譯出「APK」,在安裝時,就會噴出安裝時的錯誤,「INSTALL_FAILED_SHARED_USER_INCOMPATIBLE」,如下:

事實上,「Android OS」要求所有「APK」都必須擁有「數位簽章」才能「安裝」或「更新」至設備上,如下:

當「Android OS」在安裝「APK」時,它會去檢查該「APK」上的「數位簽章」,又因為我們在「AndroidManifest」中定義「android.uid.system」的描述,所以理論上,「APK」上的「數位簽章」必須與「系統的數位簽章」相同,否則就會噴出「INSTALL_FAILED_SHARED_USER_INCOMPATIBLE」的錯誤。

順帶一提,「debug.apk」同樣也必須帶有「數位簽章」,如下:

備註:「Debug」所用的「數位簽章」是由「IDE」自動產生,通常較不嚴謹,因此,大多數的「APP Store」,如「Google Play Store」,都不允許使用「debug certificate」來進行上架,而是必須另外產生「Signed APK」。

藉由「signapk.jar」進行數位簽章

步驟一、產生「app-debug.apk」

若你也是使用「Android Studio」,路徑如下:

「Build」->「Build Bundle(s)/APK(s)」->「Build APK(s)」

然後找到「app-debug.apk」,其路徑如下:

<APP_PROJECT_FOLDER_NAME>/app/build/outputs/apk/debug/app-debug.apk

畫面如下:

備註:在此僅須使用「debug certificate」,反正之後就會被覆蓋。

步驟二、「signapk.jar

接著是,「signapk.jar」是「Android」內建的「簽章工具」,我們使用它來對「APK」進行「簽章」,要注意的是,其為「Jar」,因此需要「Java」。

開啟「AOSP」的專案目錄,而「signapk.jar」位於路徑如下:

<AOSP_PROJECT_FOLDER_NAME>/out/host/linux-x86/framework/signapk.jar

畫面如下:

備註:若在沒有「out」資料夾,或是該路徑下沒有東西,其可能原因為該專案沒有編譯過,或是被「clean」過,只要再編譯即可。

步驟三、「platform.x509.pem」和「platform.pk8」

找到專案的「key」,分別為「platform.x509.pem」和「platform.pk8」,共兩個,其檔案路徑如下:

<AOSP_PROJECT_FOLDER_NAME>/build/target/product/security/

畫面如下:

理論上,「key」會隨著專案的項目而有所不同,是無法共用的。

步驟四、「lib64」

因為「signapk.jar」是「jar」檔,因此,我們需要「Java Library」協助,筆者的環境為「64 位元」,而其路徑如下:

<AOSP_PROJECT_FOLDER_NAME>/out/host/linux-x86/lib64/

步驟五、「Signing」

通常為了方便,筆者會把「APK」、「signapk.jar」、「key」以及「lib64」放在同一個資料夾底下,如下:

然後,直接在該目錄執行下列指令:

java -Djava.library.path=./lib64/ -jar signapk.jar platform.x509.pem platform.pk8 app-debug.apk app-debug-signed.apk

完成後就會產生檔名為「app-debug-signed.apk」的,如下:

備註:「app-debug.apk」是「APK」的檔案名稱,如果名稱有改,其指定也要隨著更改;「app-debug-signed.apk」是經過「數位簽章」後「APK」,其名稱可以自定義。

易於使用的「Shell Script」腳本

上為「Shell Script」的語言腳本。

首先,將「APK」放置在「AOSP」專案的根目錄中,並輸入指令如下:

./sign_apk.sh <YOUR_APK_FILE_NAM>

運行後,它會在同目錄下產生一個「Signed APK」,其檔案名稱格式如下:

signed_at_YYmmDDHHMMSS_<YOUR_APK_FILE_NAM>

總結

本文主要在介紹「如何使用『signapk.jar』對『APK』進行簽章的方式與觀念」,主要參考的文件為「apksigner」與「Sign your app」。

--

--

RICK
RICK

Written by RICK

當遇到重開機無法解決的 BUG 時,那就試試關機吧。

No responses yet