簽名技術(shù)
一六敬、背景知識(shí)
1. 數(shù)字摘要
數(shù)字摘要是將任意長(zhǎng)度的消息變成固定長(zhǎng)度的短消息碘赖,它類似于一個(gè)自變量是消息的函數(shù),也就是Hash函數(shù)外构。數(shù)字摘要就是采用單向Hash函數(shù)將需要加密的明文“摘要”成一串固定長(zhǎng)度(128位)的密文這一串密文又稱為數(shù)字指紋普泡,它有固定的長(zhǎng)度,而且不同的明文摘要成密文审编,其結(jié)果總是不同的撼班,而同樣的明文其摘要必定一致。
一個(gè)Hash函數(shù)的好壞是由發(fā)生碰撞的概率決定的垒酬。如果攻擊者能夠輕易地構(gòu)造出兩個(gè)消息具有相同的Hash值砰嘁,那么這樣的Hash函數(shù)是很危險(xiǎn)的。一般來(lái)說勘究,安全Hash標(biāo)準(zhǔn)的輸出長(zhǎng)度為160位矮湘,這樣才能保證它足夠的安全。 這一加密方法亦稱安全Hash編碼法(SHA:Secure Hash Algorithm)或MD5(MD Standards for Message Digest)口糕,由Ron Rivest所設(shè)計(jì)缅阳。該編碼法采用單向Hash函數(shù)將需加密的明文“摘要”成一串128bit的密文,這一串密文亦稱為數(shù)字指紋(Finger Print)景描,它有固定的長(zhǎng)度十办,且不同的明文摘要成密文秀撇,其結(jié)果總是不同的,而同樣的明文其摘要必定一致向族。這樣這摘要便可成為驗(yàn)證明文是否是“真身”的“指紋”了呵燕。
(摘自百度百科)
2. 數(shù)字簽名
數(shù)字簽名(又稱公鑰數(shù)字簽名、電子簽章)是一種類似寫在紙上的普通的物理簽名炸枣,但是使用了公鑰加密領(lǐng)域的技術(shù)實(shí)現(xiàn)虏等,用于鑒別數(shù)字信息的方法。一套數(shù)字簽名通常定義兩種互補(bǔ)的運(yùn)算适肠,一個(gè)用于簽名霍衫,另一個(gè)用于驗(yàn)證。
數(shù)字簽名侯养,就是只有信息的發(fā)送者才能產(chǎn)生的別人無(wú)法偽造的一段數(shù)字串敦跌,這段數(shù)字串同時(shí)也是對(duì)信息的發(fā)送者發(fā)送信息真實(shí)性的一個(gè)有效證明。
數(shù)字簽名是非對(duì)稱密鑰加密技術(shù)與數(shù)字摘要技術(shù)的應(yīng)用逛揩。
一般來(lái)說柠傍,非對(duì)稱加密是用來(lái)處理短消息的,而相對(duì)于較長(zhǎng)的消息則顯得有些吃力辩稽。當(dāng)然惧笛,可以將長(zhǎng)的消息分成若干小段,然后再分別簽名逞泄。不過患整,這樣做非常麻煩,而且會(huì)帶來(lái)數(shù)據(jù)完整性的問題喷众。比較合理的做法是在數(shù)字簽名前對(duì)消息先進(jìn)行數(shù)字摘要各谚。
簽名過程:
“發(fā)送報(bào)文時(shí),發(fā)送方用一個(gè)哈希函數(shù)從報(bào)文文本中生成報(bào)文摘要,然后用自己的私人密鑰對(duì)這個(gè)摘要進(jìn)行加密到千,這個(gè)加密后的摘要將作為報(bào)文的數(shù)字簽名和報(bào)文一起發(fā)送給接收方昌渤,接收方首先用與發(fā)送方一樣的哈希函數(shù)從接收到的原始報(bào)文中計(jì)算出報(bào)文摘要,接著再用發(fā)送方的公用密鑰來(lái)對(duì)報(bào)文附加的數(shù)字簽名進(jìn)行解密憔四,如果這兩個(gè)摘要相同膀息、那么接收方就能確認(rèn)該數(shù)字簽名是發(fā)送方的。
數(shù)字簽名有兩種功效:一是能確定消息確實(shí)是由發(fā)送方簽名并發(fā)出來(lái)的了赵,因?yàn)閯e人假冒不了發(fā)送方的簽名潜支。二是數(shù)字簽名能確定消息的完整性。因?yàn)閿?shù)字簽名的特點(diǎn)是它代表了文件的特征斟览,文件如果發(fā)生改變,數(shù)字摘要的值也將發(fā)生變化辑奈。不同的文件將得到不同的數(shù)字摘要苛茂。 一次數(shù)字簽名涉及到一個(gè)哈希函數(shù)已烤、發(fā)送者的公鑰、發(fā)送者的私鑰妓羊】杈浚”
數(shù)字簽名:
發(fā)送方用自己的密鑰對(duì)報(bào)文X進(jìn)行Encrypt(編碼)運(yùn)算,生成不可讀取的密文Dsk躁绸,然后將Dsk傳送給接收方裕循,接收方為了核實(shí)簽名,用發(fā)送方的公用密鑰進(jìn)行Decrypt(解碼)運(yùn)算净刮,還原報(bào)文剥哑。
數(shù)字簽名工作原理圖
(摘自百度百科)
二、 Android 應(yīng)用簽名過程
三淹父、 Android 應(yīng)用簽名驗(yàn)證過程
四株婴、Others
APK簽名方案:
4.1 方案1-基于JAR簽名的方案
從一開始,APK 簽名就是 Android 的一個(gè)有機(jī)部分暑认。該方案基于簽名的 JAR困介。如要詳細(xì)了解如何使用該方案,請(qǐng)參閱介紹如何為您的應(yīng)用簽名的 Android Studio 文檔蘸际。
v1 簽名不保護(hù) APK 的某些部分座哩,例如 ZIP 元數(shù)據(jù)。APK 驗(yàn)證程序需要處理大量不可信(尚未經(jīng)過驗(yàn)證)的數(shù)據(jù)結(jié)構(gòu)粮彤,然后會(huì)舍棄不受簽名保護(hù)的數(shù)據(jù)根穷。這會(huì)導(dǎo)致相當(dāng)大的受攻擊面。此外驾诈,APK 驗(yàn)證程序必須解壓所有已壓縮的條目缠诅,而這需要花費(fèi)更多時(shí)間和內(nèi)存。為了解決這些問題乍迄,Android 7.0 中引入了 APK 簽名方案 v2管引。
4.2 方案2-基于Apk的簽名方案
Android 7.0 中引入了 APK 簽名方案 v2(v2 方案)。該方案會(huì)對(duì) APK 的內(nèi)容進(jìn)行哈希處理和簽名闯两,然后將生成的“APK 簽名分塊”插入到 APK 中褥伴。如要詳細(xì)了解如何在應(yīng)用中使用 v2 方案,請(qǐng)參閱 Android N 開發(fā)者預(yù)覽版中的 APK 簽名方案 v2漾狼。
在驗(yàn)證期間重慢,v2 方案會(huì)將 APK 文件視為 Blob,并對(duì)整個(gè)文件進(jìn)行簽名檢查逊躁。對(duì) APK 進(jìn)行的任何修改(包括對(duì) ZIP 元數(shù)據(jù)進(jìn)行的修改)都會(huì)使 APK 簽名作廢似踱。這種形式的 APK 驗(yàn)證不僅速度要快得多,而且能夠發(fā)現(xiàn)更多種未經(jīng)授權(quán)的修改。
新的簽名格式向后兼容核芽,因此囚戚,使用這種新格式簽名的 APK 可在更低版本的 Android 設(shè)備上進(jìn)行安裝(會(huì)直接忽略添加到 APK 的額外數(shù)據(jù)),但前提是這些 APK 還帶有 v1 簽名轧简。
驗(yàn)證程序會(huì)對(duì)照存儲(chǔ)在“APK 簽名分塊”中的 v2 簽名對(duì) APK 的全文件哈希進(jìn)行驗(yàn)證驰坊。該哈希涵蓋除“APK 簽名分塊”(其中包含 v2 簽名)之外的所有內(nèi)容。在“APK 簽名分塊”以外對(duì) APK 進(jìn)行的任何修改都會(huì)使 APK 的 v2 簽名作廢哮独。v2 簽名被刪除的 APK 也會(huì)被拒絕拳芙,因?yàn)?v1 簽名指明相應(yīng) APK 帶有 v2 簽名,所以 Android Nougat 及更高版本會(huì)拒絕使用 v1 簽名驗(yàn)證 APK皮璧。
如需關(guān)于 APK 簽名驗(yàn)證過程的詳細(xì)信息舟扎,請(qǐng)參閱 APK 簽名方案 v2 的“驗(yàn)證”部分。
4.3 APK 簽名方案 v2 驗(yàn)證
- 找到“APK 簽名分塊”并驗(yàn)證以下內(nèi)容:
“APK 簽名分塊”的兩個(gè)大小字段包含相同的值恶导。
“ZIP 中央目錄結(jié)尾”緊跟在“ZIP 中央目錄”記錄后面浆竭。
“ZIP 中央目錄結(jié)尾”之后沒有任何數(shù)據(jù)。 - 找到“APK 簽名分塊”中的第一個(gè)“APK 簽名方案 v2 分塊”惨寿。如果 v2 分塊存在邦泄,則繼續(xù)執(zhí)行第 3 步。否則裂垦,回退至使用 v1 方案驗(yàn)證 APK顺囊。
- 對(duì)“APK 簽名方案 v2 分塊”中的每個(gè) signer 執(zhí)行以下操作:
a. 從 signatures 中選擇安全系數(shù)最高的受支持 signature algorithm ID。安全系數(shù)排序取決于各個(gè)實(shí)現(xiàn)/平臺(tái)版本蕉拢。
b.使用 public key 并對(duì)照 signed data 驗(yàn)證 signatures 中對(duì)應(yīng)的 signature特碳。(現(xiàn)在可以安全地解析 signed data 了。)
c.驗(yàn)證 digests 和 signatures 中的簽名算法 ID 列表(有序列表)是否相同晕换。(這是為了防止刪除/添加簽名午乓。)
d.使用簽名算法所用的同一種摘要算法計(jì)算 APK 內(nèi)容的摘要。
e.驗(yàn)證計(jì)算出的摘要是否與 digests 中對(duì)應(yīng)的 digest 相同闸准。
f.驗(yàn)證 certificates 中第一個(gè) certificate 的 SubjectPublicKeyInfo 是否與 public key 相同益愈。 - 如果找到了至少一個(gè) signer,并且對(duì)于每個(gè)找到的 signer夷家,第 3 步都取得了成功蒸其,APK 驗(yàn)證將會(huì)成功。
注意:如果第 3 步或第 4 步失敗了库快,則不得使用 v1 方案驗(yàn)證 APK摸袁。
4.4 JAR 已簽名的 APK 的驗(yàn)證(v1 方案)
JAR 已簽名的 APK 是一種標(biāo)準(zhǔn)的已簽名 JAR,其中包含的條目必須與 META-INF/MANIFEST.MF 中列出的條目完全相同义屏,并且所有條目都必須已由同一組簽名者簽名靠汁。其完整性按照以下方式進(jìn)行驗(yàn)證:
- 每個(gè)簽名者均由一個(gè)包含 META-INF/<signer>.SF 和 META-INF/<signer>.(RSA|DSA|EC) 的 JAR 條目來(lái)表示蜂大。
- <signer>.(RSA|DSA|EC) 是具有 SignedData 結(jié)構(gòu)的 PKCS #7 CMS ContentInfo,其簽名通過 <signer>.SF 文件進(jìn)行驗(yàn)證蝶怔。
3.<signer>.SF 文件包含 META-INF/MANIFEST.MF 的全文件摘要和 META-INF/MANIFEST.MF 各個(gè)部分的摘要县爬。需要驗(yàn)證 MANIFEST.MF 的全文件摘要。如果該驗(yàn)證失敗添谊,則改為驗(yàn)證 MANIFEST.MF 各個(gè)部分的摘要。 - 對(duì)于每個(gè)受完整性保護(hù)的 JAR 條目察迟,META-INF/MANIFEST.MF 都包含一個(gè)具有相應(yīng)名稱的部分斩狱,其中包含相應(yīng)條目未壓縮內(nèi)容的摘要。所有這些摘要都需要驗(yàn)證扎瓶。
5.如果 APK 包含未在 MANIFEST.MF 中列出且不屬于 JAR 簽名一部分的 JAR 條目所踊,APK 驗(yàn)證將會(huì)失敗。
因此概荷,保護(hù)鏈?zhǔn)敲總€(gè)受完整性保護(hù)的 JAR 條目的 <signer>.(RSA|DSA|EC) -> <signer>.SF -> MANIFEST.MF -> 內(nèi)容秕岛。
四、 參考資料
https://docs.oracle.com/javase/8/docs/technotes/guides/jar/jar.html#Signed_JAR_File
https://source.android.com/security/apksigning/?hl=zh-cn
https://baike.baidu.com/item/%E6%95%B0%E5%AD%97%E7%AD%BE%E5%90%8D
http://www.reibang.com/p/6f8fc521512e(apk安裝過程误证,其中包含了簽名驗(yàn)證)
http://blog.csdn.net/jiangwei0910410003/article/details/50402000
https://source.android.com/security/overview/app-security?hl=zh-cn
http://blog.csdn.net/u013836857/article/details/51445532