???????普法Android系統各類簽名以及關聯Key知識
本篇博客撰寫思路總結和關鍵點說明:

為了更加方便的讀者閱讀博客,通過導讀思維圖的形式將本博客的關鍵點列舉出來,從而方便讀者取舍和閱讀!
引言
??對于Android的簽名機制,無論你是應用開發者還是Android系統層級開發者來說都是一個繞不過的知識點!為什么這么說呢?假如你是應用開發者,你一定會給你的應用apk加上自己或者公司的簽名防止被被第三方惡意篡改,假如你是Android系統ROM層級開發者,當我們要發布一款Android產品,就需要給我們的整個Android系統簽名,防止被別 人盜用,通常這種簽名被成為系統級別的release簽名,
當然本篇博客的重點不是討論Android應用App簽名的發展史(譬如V1,V2簽名啊),也不是討論Android的簽名驗簽機制的,我這里寫該博客的出發點是想站在Android系統ROM的開發角度出發來對Android的相關簽名和key簡單分析一番,正如標題所說普法Android系統各類簽名以及關聯Key知識那樣,
注意:本篇的介紹是基于Android 7.xx平臺為基礎的,其中涉及的代碼路徑如下:
build/target/product/security/
development/tools/make_key
一.什么是簽名
??假如這個問題不是放在Android開發的環境來問,讀者很快就能給出答復了!可放在Android開發中來詢問何為簽名,大家就開始迷惑了或者需要一定的時間來組織語言回復了,其實從發展的角度來看,計算機所做的事情,或者說編程語言所做的事情,不正是在盡可能地模擬現實嗎?所以,Android中所說的簽名和生活中所說的簽名在本質上是一樣的,它所起到的作用也是一致的!我們在現實中的簽名就意味著在紙上或別處寫下自己的名字,或者說在某處打上一個標記作為你自己的一種特有的標識,當別人看到這個簽名的時候,他會知道這是和你有關的,而不是其它人,而在Android中的簽名就是對我們的App或者系統韌體加上特定的一些資訊,防止被惡意篡改而已,而加上的這些特定資訊就是簽名(至于怎么加上,以及怎么驗證這個不是本篇博客的重點,我會在最后附上相關的一些參考如果有感興趣的小伙們),
二.Android簽名的作用
??關于Android應用簽名的作用,必須從兩個角度出發,即Android應用開發者和Android系統的設計角度出發!下面我們就從這兩個角度出發,簡單的介紹一下,
2.1 站在Android應用開發角度看Android簽名的作用
從Android應用開發者的角度出發來說,Android的簽名作用可以從如下兩個方面體現:
- 確保應用開發者身份的唯一性,因為Android應用的包名是可以任意替換的,假如某某公司或者個人開發了一個現象級的應用的,如果沒有簽名來保證App的唯一性,那么Android的世界應該就亂套了,會出現無數的模仿者,更有甚者會制作出一個一模一樣的包名的應用替換它
- 保證Apk在資訊傳輸中的的完整性,簽名對于包中的每個檔案進行處理,以此確保包中內容不被替換或者被篡改,這也是為什們通常建議大家在正規渠道下載App的原因,特別是對于一些涉及金錢交易的Apk來說更是如此(譬如植入惡意木馬程式),被盜取個人資訊甚至是金錢,那這個損失是找開發者還是誰呢,誰也說不清楚
2.2 站在Android設計者的角度出發看Android簽名的作用
站在Android設計者的角度出發,那么他所要考慮的角度就比較高了,但是無外乎如下幾點:
-
為了應用程式升級:如果你希望用戶無縫升級到新的版本,那么你必須用同一個證書進行簽名,這是由于只有以同一個證書簽名,系統才會允許安裝升級的應用程式,如果你采用了不同的證書,那么系統會要求你的應用程式采用不同的包名稱,在這種情況下相當于安裝了一個全新的應用程式,如果想升級應用程式,簽名證書要相同,包名稱要相同!
-
為了應用程式模塊化:Android系統可以允許同一個證書簽名的多個應用程式在一個行程里運行,系統實際把他們作為一個單個的應用程式,此時就可以把我們的應用程式以模塊的方式進行部署,而用戶可以獨立的升級其中的一個模塊
-
為了代碼或者資料共享:Android提供了基于簽名的權限機制,那么一個應用程式就可以為另一個以相同證書簽名的應用程式公開自己的功能,以同一個證書對多個應用程式進行簽名,利用基于簽名的權限檢查,你就可以在應用程式間以安全的方式共享代碼和資料了,
-
為了Android韌體的安全考慮:我們知道Android可以系統版本進行OTA的升級,那么Android是怎么確保升級的韌體是合法的呢,這個就是對OTA包進行簽名,然后在進行Recovery升級的時候來驗證OTA的簽名來確保韌體的合法和唯一性
而Android為了實作上述的功能,就離不開各種簽名檔案和相關的key了,而這個也是本篇博客比較篇章的知識點了!
三.Android系統簽名檔案簡介
??通過前面的分析我們知道Android為我們提供了各種型別的簽名檔案,所以我們肯定的必須的來熟悉一番,甚至更進一步的掌握一番才是,但是在這之間我們有必要先來看個東西,啥東西呢,這就安排上了,
3.1 什么是.pem和.pk8檔案
??這里為啥突然整個啥.pem和.pkm檔案來說呢,因為它們是我們Android系統簽名檔案的最終載體,并且二者幾乎是成對存在的,我們先來分別接啥一下.
-
.pem型別檔案:
在android對apk簽名的時候,.pem這種檔案就是一個X.509的數字證書,里面有用戶的公鑰等資訊,是用來解密的,檔案格式里面不僅可以存盤數字證書,還能存各種key,這個可以公開,主要用于驗證某個App或者其它的是否由相應的私鑰簽名 -
.pk8
以.pk8為擴展名的檔案,應該和PKCS #8是對應的,用來保存private key,并且這個私鑰需要保密保存,不能公開
3.2 Android中存在那些型別的系統簽名
??有了前面的鋪墊,我們來看看Android的設計者為我們設計了那些型別的系統簽名(注意這里的系統簽名,不是特指system),通常Android原始碼中的系統簽名都被統一存放在了Android的原始碼build/target/product/security中,我們來看下:
XXXX:/build/target/product/security$ tree
.
├── Android.mk
├── media.pk8
├── media.x509.pem
├── platform.pk8
├── platform.x509.pem
├── README
├── shared.pk8
├── shared.x509.pem
├── testkey.pem
├── testkey.pk8
├── testkey.x509.pem
├── verity_key
├── verity.pk8
└── verity.x509.pem
0 directories, 14 files
這里我們可以看到主要有media,platform,shared,testkey等4個系統默認預置的簽名(關于這幾個簽名其功能這個后續介紹)!
并且老司機們應該都知道通常Android原始碼中的README都比較重要,這里也不列外的Android的設計者為我們貼心的也提供了,建議讀者抽時間看看(主要介紹了怎么通過內置工具生成和替換系統默認預置的各種key,以及各種key的簡單使用實體)!
For detailed information on key types and image signing, please see:
https://source.android.com/devices/tech/ota/sign_builds.html
The test keys in this directory are used in development only and should
NEVER be used to sign packages in publicly released images (as that would
open a major security hole).
key generation
--------------
The following commands were used to generate the test key pairs:
development/tools/make_key testkey '/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/emailAddress=android@android.com'
development/tools/make_key platform '/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/emailAddress=android@android.com'
development/tools/make_key shared '/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/emailAddress=android@android.com'
development/tools/make_key media '/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/emailAddress=android@android.com'
signing using the openssl commandline (for boot/system images)
--------------------------------------------------------------
1. convert pk8 format key to pem format
% openssl pkcs8 -inform DER -nocrypt -in testkey.pk8 -out testkey.pem
2. create a signature using the pem format key
% openssl dgst -binary -sha1 -sign testkey.pem FILE > FILE.sig
extracting public keys for embedding
------------------------------------
dumpkey.jar is a Java tool that takes an x.509 certificate in PEM format as
input and prints a C structure to standard output:
$ java -jar out/host/linux-x86/framework/dumpkey.jar build/target/product/security/testkey.x509.pem
{64,0xc926ad21,{1795090719,2141396315,950055447,2581568430,4268923165,1920809988,546586521,3498997798,1776797858,3740060814,1805317999,1429410244,129622599,1422441418,1783893377,1222374759,2563319927,323993566,28517732,609753416,1826472888,215237850,4261642700,4049082591,3228462402,774857746,154822455,2497198897,2758199418,3019015328,2794777644,87251430,2534927978,120774784,571297800,3695899472,2479925187,3811625450,3401832990,2394869647,3267246207,950095497,555058928,414729973,1136544882,3044590084,465547824,4058146728,2731796054,1689838846,3890756939,1048029507,895090649,247140249,178744550,3547885223,3165179243,109881576,3944604415,1044303212,3772373029,2985150306,3737520932,3599964420},{3437017481,3784475129,2800224972,3086222688,251333580,2131931323,512774938,325948880,2657486437,2102694287,3820568226,792812816,1026422502,2053275343,2800889200,3113586810,165549746,4273519969,4065247892,1902789247,772932719,3941848426,3652744109,216871947,3164400649,1942378755,3996765851,1055777370,964047799,629391717,2232744317,3910558992,191868569,2758883837,3682816752,2997714732,2702529250,3570700455,3776873832,3924067546,3555689545,2758825434,1323144535,61311905,1997411085,376844204,213777604,4077323584,9135381,1625809335,2804742137,2952293945,1117190829,4237312782,1825108855,3013147971,1111251351,2568837572,1684324211,2520978805,367251975,810756730,2353784344,1175080310}}
This is called by build/core/Makefile to incorporate the OTA signing keys
into the recovery image.
3.3 Android中各型別簽名檔案的用途
??在分析Android中各型別簽名檔案的用途之前,我們有必要來簡單先掰持掰持Android中的sharedUserId,因為Android設計出這么多簽名檔案的意圖絕大部分是為了它,
3.3.1 Android中sharedUserId的作用
我們知道Android設備中每一個正常安裝的Apk,在其安裝的時候Android就會給每個APK行程分配一個單獨的用戶空間,其AndroidManifest中的userid就是對應一個Linux用戶都會被分配到一個屬于自己的統一的Linux用戶ID,并且為它創建一個沙箱,以防止其它應用非法寫入或者篡改,當然也有可能是它非法篡改或者寫入其它的應用,譬如一般應用只能訪問自己包名下的檔案(/data/data/pkgname),不能反問其他包名下的data資料,當然其他應用也訪問不了自己包名下的檔案(這里需要注意一點的就是用戶ID在應用程式安裝到設備中時被分配,并且在這個設備中保持它的永久性),
上述的的沙箱隔離機制是非常好的,但是開發的程序中用戶和使用者的需求有時候和設計者是矛盾的,那么假如同一個公司開發的A應用想拿到B應用的data下面的資料怎么辦呢!這里就要引出我們的sharedUserId了,我們可以通過Shared User id,擁有同一個User id的多個APK可以配置成運行在同一個行程中.所以默認就是可以互相訪問任意資料. 也可以配置成運行成不同的行程, 同時可以訪問其他APK的資料目錄下的資料庫和檔案.就像訪問本程式的資料一樣.,
3.3.2 Android怎么使用sharedUserId
前面講述sharedUserId的作用,那么我們在原始碼中怎么實作Android的sharedUserId呢,其主要步驟如下:
- 在AndroidManifest節點中增加android:sharedUserId屬性,如下
android:sharedUserId="android.uid.system"
- 在Android.mk中增加LOCAL_CERTIFICATE的定義,即可以完成編譯時指定簽名檔案,如下
LOCAL_CERTIFICATE := platform
- 然后將上述Apk匯入原始碼中,通過mm或者mmm編譯
上述都是Android開發中的常規操作,沒有啥可以好講的!
但是上面有一定需要注意sharedUserId屬性一定要和LOCAL_CERTIFICATE匹配,否則Apk簽名以后安裝是不會成功的,提示如下錯誤:
Failure [INSTALL_FAILED_UPDATE_INCOMPATIBLE: Package com.xxx.xxxsignatures do not match the previously installed version; ignoring!]
從上面我們可以看出,僅有相同簽名和相同sharedUserID應用才能被正常安裝,放大了來講就是僅有相同簽名和相同sharedUserID標簽的兩個應用程式Apk才會被分配相同的用戶ID才能訪問對方的私有資料,從而達到既能訪問又能保證安全的機制,
但是這里的platform的簽名還有點特殊,它不僅可以和system的sharedUserId配合,它還可以和其它的sharedUserId配合,譬如phone,nfc,bluetooth等!
3.3.3 Android的sharedUserId和簽名檔案的關聯
經過上面的一通掰持掰持,我想讀者應該能理解sharedUserId和簽名檔案的作用了,即通過sharedUserId標簽,和簽名一通配合,從而是Apk應用配相同的用戶ID,進而實作資料共享的目的,但是如果僅有sharedUserId標簽的話,是無法確保安全的,也很容易被非法利用,所以這才引入了各種簽名,
3.3.4 Android系統中簽名檔案的作用說明
是時候進入本節標題的正題了,前面我們引入了簽名檔案設計的意圖,下面我們分別來介紹下這幾種簽名檔案的功能!
-
platform:通常用于Android平臺的核心Apk簽名,它們通常用來完成Android系統的核心功能,這些Apk所在的行程UID是system,并且其AndroidManifest節點中配置android:sharedUserId=“android.uid.system”,我們最常見的莫過于Settings了,并且上述的簽名也是很多第三方Apk夢寐以求的,擁有了它就可以干一些超出尋常權限的事情了(至于是什么事情,這個讀者自行腦補了)!
這里需要注意一點,我們在ps的時候會看到一些Native層的bin檔案也會是system的uid,它的實作方式和我們這里是有點區別的,這里需要注意,它并不是通過簽名來實作的,而是通過運行的時候指定UID和GUID來實作的,
如下:
service fingerprintd /system/bin/fingerprintd
class late_start
user system
group system
ps | grep system
system 5644 513 843248 36512 SyS_epoll_ b27754e8 S com.android.keychain
system 5823 513 848436 38328 SyS_epoll_ b27754e8 S com.qualcomm.location.XT
system 6030 513 842904 35436 SyS_epoll_ b27754e8 S com.qualcomm.telephony
system 6117 513 843504 35876 SyS_epoll_ b27754e8 S com.qualcomm.timeservice
system 5017 513 889712 53660 SyS_epoll_ b27754e8 S com.android.settings
-
shared:這個簽名的Apk通常用于和Contacts共享資料,至于Apk怎么使用和配置就不細述了,同上即可,

-
media:看這個簽名key的名字就很明顯了,它通常用于多媒體相關的Apk使用,譬如Gallery,至于Apk怎么使用和配置就不細述了,同上即可(但是這里注意它的配置是android.media不是android.uid.media,注意注意),

- testkey:testkey是Android平臺默認編譯的key,所以在Android的原始碼編譯中如果未指定LOCAL_CERTIFICATE的值,則默認使用testkey,但是因為因為testkey是Android進行公開的,任何人都可以獲取,不安全,所以一般使用 自己創建releasekey作為默認key(至于怎么生成releasekey這個后面講述)!
這里有一點我們需要注意,當我們預置第三方的App時,并不想使用Android系統的相關簽名,而是想保留它的原有簽名,可以通過如下的方法:
LOCAL_CERTIFICATE := PRESIGNED
四.從實戰和原始碼的角度說說Android的簽名
通過前面,讀者應該對Android為什么設計簽名和Android中存在那些簽名應該很了解了!通常我們在實際的開發作業中會對Android的簽名進行相關的定制,這里我們就從實戰的角度來說說Android的簽名,
在開始本節之間,最好先簡單了解一下openssl命令!
4.1 生成平臺自己的releasekey
我們前面說到testkey是Android平臺默認編譯的key(APK的默認簽名,OTA的簽名等),但是因為testkey是Android進行公開的,任何人都可以獲取,不安全,所以一般使用 自己創建releasekey作為默認key,這里Android為了方便我們的開發者默認提供了一個快速生成各種key的命令工具集development/tools/make_key,關于它的使用在前面的README中有詳細介紹,這里我們提供一個腳本一鍵生成相關的4個key,如下:
#!/bin/bash
subject='/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/emailAddress=android@android.com'
mkdir ~/.android-certs
for x in releasekey platform shared media; do \
./development/tools/make_key ~/.android-certs/$x "$subject"; \
done
注意該腳本要在我們的Android原始碼的根目錄執行,并且對上述腳本需要執行權限,我們執行一下(注意在執行的程序中,當提示我們輸入密碼的時候,我們直接按Enter按鍵,不是用密碼,否則在后續使用的程序中會提示我們輸入密碼):
Enter password for '/home/xxx/.android-certs/releasekey' (blank for none; password will be visible):
creating /home/xxx/.android-certs/releasekey.pk8 with no password
Generating RSA private key, 2048 bit long modulus
.....................................+++
..................+++
e is 65537 (0x10001)
執行以后會在我們的服務器的用戶目錄下生成我們需要的key,如下:
XXX@pd:~/.android-certs$ tree
.
├── media.pk8
├── media.x509.pem
├── platform.pk8
├── platform.x509.pem
├── releasekey.pk8
├── releasekey.x509.pem
├── shared.pk8
└── shared.x509.pem
0 directories, 8 files
XXX@pd:~/.android-certs$
這我們重點關于的是上述腳本中的subject,它被成為我們的證書的主題(Subjuect)欄位,其中每個欄位的基本含義定義如下:
一般的數字證書產品的主題通常含有如下欄位:
公用名稱 (Common Name) 簡稱:CN 欄位,對于 SSL 證書,一般為網站域名或IP地址;而對于代碼簽名證書則為申請單位名稱;而對于客戶端證書則為證書申請者的姓名;
單位名稱 (Organization Name) :簡稱:O 欄位,對于 SSL 證書,一般為網站域名;而對于代碼簽名證書則為申請單位名稱;而對于客戶端單位證書則為證書申請者所在單位名稱;
證書申請單位所在地:
所在城市 (Locality) 簡稱:L 欄位
所在省份 (State/Provice) 簡稱:S 欄位
所在國家 (Country) 簡稱:C 欄位,只能是國家字母縮寫,如中國:CN
其他一些欄位:
電子郵件 (Email) 簡稱:E 欄位
多個姓名欄位 簡稱:G 欄位
介紹:Description 欄位
電話號碼:Phone 欄位,格式要求 + 國家區號 城市區號 電話號碼,如: +86 732 88888888
地址:STREET 欄位
郵政編碼:PostalCode 欄位
顯示其他內容 簡稱:OU 欄位
4.1.1 make_key腳本簡介
這里我們也可以看到上述的命令的最終實作的最大功臣是make_key腳本,我們看看它里面有啥:
#!/bin/bash
if [ "$#" -lt 2 -o "$#" -gt 3 ]; then
cat <<EOF
Usage: $0 <name> <subject> [<keytype>]
Creates <name>.pk8 key and <name>.x509.pem cert. Cert contains the
given <subject>. A keytype of "rsa" or "ec" is accepted.
EOF
exit 2
fi
if [[ -e $1.pk8 || -e $1.x509.pem ]]; then
echo "$1.pk8 and/or $1.x509.pem already exist; please delete them first"
echo "if you want to replace them."
exit 1
fi
# Use named pipes to connect get the raw RSA private key to the cert-
# and .pk8-creating programs, to avoid having the private key ever
# touch the disk.
tmpdir=$(mktemp -d)
trap 'rm -rf ${tmpdir}; echo; exit 1' EXIT INT QUIT
one=${tmpdir}/one
two=${tmpdir}/two
mknod ${one} p
mknod ${two} p
chmod 0600 ${one} ${two}
read -p "Enter password for '$1' (blank for none; password will be visible): " \
password
if [ "${3}" = "rsa" -o "$#" -eq 2 ]; then
( openssl genrsa -f4 2048 | tee ${one} > ${two} ) &
hash="-sha1"
elif [ "${3}" = "ec" ]; then
( openssl ecparam -name prime256v1 -genkey -noout | tee ${one} > ${two} ) &
hash="-sha256"
else
echo "Only accepts RSA or EC keytypes."
exit 1
fi
openssl req -new -x509 ${hash} -key ${two} -out $1.x509.pem \
-days 10000 -subj "$2" &
if [ "${password}" == "" ]; then
echo "creating ${1}.pk8 with no password"
openssl pkcs8 -in ${one} -topk8 -outform DER -out $1.pk8 -nocrypt
else
echo "creating ${1}.pk8 with password [${password}]"
export password
openssl pkcs8 -in ${one} -topk8 -outform DER -out $1.pk8 \
-passout env:password
unset password
fi
wait
wait
可以看到它里面主要是封裝了openssl命令,然后通過我們的輸入生成我們需要的公私鑰!其大概步驟如下(這個讀者可以自行傳入不同的引數,自行測驗):
- 生成公鑰(關于openssl genrsa的使用,可以借助幫助命令openssl genrsa --help)
openssl genrsa -f4 2048 releasekey.pem
- 將上述生成的公鑰,轉換成x509格式
openssl req -new -x509 -sha1 -key releasekey.pem -out releasekey.x509.pem \
-days 10000 -subj /C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/emailAddress=android@android.com
- 最后就是生成和公鑰配對的私鑰了,這里可以看到有指定了非加密的形式
openssl pkcs8 -in releasekey.pem -topk8 -outform DER -out releasekey.pk8 -nocrypt
4.2 自定義平臺自己的默認key
好了,前面我們的releasekey也生成了,那么我們怎么指定我們平臺自己的releasekey呢,其操作步驟流程如下:
- 將前面生成的releasekey(包括pem檔案和pk8檔案)放入build/target/product/security/中
- 在我們的編譯device相關的mk或者build/core/config.mk指定PRODUCT_DEFAULT_DEV_CERTIFICATE := build/target/product/security/releasekey即可
//[config.mk]
# The default key if not set as LOCAL_CERTIFICATE
ifdef PRODUCT_DEFAULT_DEV_CERTIFICATE
DEFAULT_SYSTEM_DEV_CERTIFICATE := $(PRODUCT_DEFAULT_DEV_CERTIFICATE)
else
DEFAULT_SYSTEM_DEV_CERTIFICATE := build/target/product/security/testkey
endif
經過如上已讀折騰就萬事OK了,
這里我么還有一點需要就是,我面前面有說過可以通過LOCAL_CERTIFICATE指定我們Apk的簽名檔案嗎,這是怎么做到的呢?我們可以到我們原始碼目錄下build/下執行如下命令grep一下就大概明白了,具體的呼叫編譯流程我就不分析了,
XXX@pd:~/XXX/build$ grep -nr "DEFAULT_SYSTEM_DEV_CERTIFICATE" ./
./core/product.mk:286: DEFAULT_SYSTEM_DEV_CERTIFICATE \
./core/Makefile:122:ifeq ($(DEFAULT_SYSTEM_DEV_CERTIFICATE),build/target/product/security/testkey)
./core/Makefile:401:DEFAULT_KEY_CERT_PAIR := $(DEFAULT_SYSTEM_DEV_CERTIFICATE)
./core/Makefile:980: @echo "default_system_dev_certificate=$(DEFAULT_SYSTEM_DEV_CERTIFICATE)" >> $(ota_temp_root)/META/misc_info.txt
./core/Makefile:1035:OTA_PUBLIC_KEYS := $(DEFAULT_SYSTEM_DEV_CERTIFICATE).x509.pem
./core/Makefile:1947: $(hide) echo "default_system_dev_certificate=$(DEFAULT_SYSTEM_DEV_CERTIFICATE)" >> $(zip_root)/META/misc_info.txt
./core/config.mk:626: DEFAULT_SYSTEM_DEV_CERTIFICATE := $(PRODUCT_DEFAULT_DEV_CERTIFICATE)
./core/config.mk:628: DEFAULT_SYSTEM_DEV_CERTIFICATE := build/target/product/security/testkey
./core/package_internal.mk:480: LOCAL_CERTIFICATE := $(DEFAULT_SYSTEM_DEV_CERTIFICATE)
./core/package_internal.mk:487: LOCAL_CERTIFICATE := $(DEFAULT_SYSTEM_DEV_CERTIFICATE)
./core/package_internal.mk:493: LOCAL_CERTIFICATE := $(dir $(DEFAULT_SYSTEM_DEV_CERTIFICATE))$(LOCAL_CERTIFICATE)
./core/prebuilt_internal.mk:200: LOCAL_CERTIFICATE := $(DEFAULT_SYSTEM_DEV_CERTIFICATE)
./core/prebuilt_internal.mk:222: LOCAL_CERTIFICATE := $(dir $(DEFAULT_SYSTEM_DEV_CERTIFICATE))$(LOCAL_CERTIFICATE)

4.3 手動使用Android的簽名檔案,簽名第三方App
有時候我們在開發的程序中,想通過命令的形式Android的系統簽名檔案簽發第三方的App,從而使獲取system權限,我們可以通過如下的腳本執行:
//
# #!/bin/bash
java -jar signapk.jar platform.x509.pem platform.pk8 $1 $2
我們來執行一把,生成簽名App檔案,如下:

這個命令沒有過多好說的,其中的signapk.jar在我們的Android原始碼中已經有提供了(當然網上也有下載)!
XXX$ find . -name signapk.jar
./out/host/linux-x86/framework/signapk.jar
./prebuilts/sdk/tools/lib/signapk.jar
這里需要注意的是上述公私鑰的位置不要搞錯了,否則會報下述的錯誤!

4.4 查看apk的簽名資訊
上述簽名也成功了,但是我們怎么驗證簽名成功了呢,好嗎這個已經有命令可以進行相關的驗證,如下:
keytool -printcert -jarfile xxx.apk
對我們簽名的簽名Apk驗證一把,得到如下資訊:

和我們前面生成的簽名檔案資訊匹配上了!
寫在最后
??普法Android系統各類簽名以及關聯Key知識的就到這里告一段落了,通過這篇博客的學習我想讀者對于Android的簽名以及各關聯的key應該有了一個基本的了解了,但是這是遠遠不夠的因為Android的簽名和驗證還牽涉到很多相關的知識,這個就在于讀者更加深入的閱讀和學習了,正如標題所說本篇博客只是起到一個普法的作用罷了,好了,最后歡迎讀者點贊和評論,青山不改綠水長流各位江湖見!
對于有想更加深入的可以參見如下博客:
Android簽名檔案轉化為pk8和pem的實作
Android應用程式簽名詳解
詳解Android v1、v2、v3簽名
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/226895.html
標籤:其他
