0x01 APK應(yīng)用程序是否簽名異常的檢測方法
要在Android上安裝APK必須要進(jìn)行數(shù)字簽名,數(shù)字簽名用于驗證應(yīng)用程序更新的所有者身份,驗證的目的是為了防止APK應(yīng)用程序被篡改或修改APK來包含惡意代碼
對 APK 進(jìn)行簽名時,會附加一個公鑰證書,這個證書是將 APK 應(yīng)用程序與開發(fā)者和開發(fā)者的私鑰進(jìn)行關(guān)聯(lián)
注:在調(diào)試模式下構(gòu)建應(yīng)用時,Android SDK 會使用專門為調(diào)試目的創(chuàng)建的調(diào)試密鑰對我們要打包的APK應(yīng)用程序進(jìn)行簽名,需要注意使用調(diào)試密鑰簽名的應(yīng)用并不會在大多數(shù)APK應(yīng)用商店中被接受和允許上架
應(yīng)用程序的最終發(fā)布版本(上線生產(chǎn)版本)必須使用有效的發(fā)布版本的密鑰進(jìn)行簽名。在 Android Studio 中,APK可手動或通過創(chuàng)建分配給發(fā)布構(gòu)建類型的簽名配置來對應(yīng)用進(jìn)行APK的簽名
Android 9(API 級別 28)之前的 Android 上,所有的應(yīng)用程序更新都需要使用相同的證書進(jìn)行簽名,所以開發(fā)者可以考慮使用 25 年或更長的有效期
注:需要注意,如果在 Google Play 上發(fā)布的應(yīng)用必須使用有效期在 2033 年 10 月 22 日之后結(jié)束的密鑰進(jìn)行簽名
三種 APK 簽名方案:
v1 方案:JAR 簽名
v2 方案:APK 簽名方案 v2
v3 方案:APK 簽名方案 v3
與 v1 方案相比,Android 7.0(API 級別 24)及更高版本支持的 v2 簽名,且提供了更高的安全性和性能。Android 9(API 級別 28)及以上版本支持的 V3 簽名,使應(yīng)用程序能夠更改其簽名密鑰,作為APK 更新的一部分,此功能通過允許同時使用新/舊密鑰,保證了兼容性和應(yīng)用程序的持續(xù)可用性。需要注意對于每個簽名方案,發(fā)布APK版本也應(yīng)該始終通過之前內(nèi)部評估好的方案進(jìn)行簽名
在做靜態(tài)分析(當(dāng)然動態(tài)分析時跟這個一樣,將APK導(dǎo)出來用jarsigner或apksigner工具來驗證APK的簽名是否異常)APK時,我們要確認(rèn)幾個重要的信息,比如APK的發(fā)布版本是 Android 7.0(API 級別 24)及更高版本的 v1 和 v2 方案以及 Android 9(API 級別 28)及更高版本的所有三個方案進(jìn)行簽名,且 APK 應(yīng)用程序中的簽名證書是屬于開發(fā)者的
我們可以使用 Android SDK 構(gòu)建工具的修訂版 24.0.3 及更高版本中提供的 apksigner 工具為 APK 簽名,并確保 APK 的簽名能夠在 APK 支持的所有版本的 Android 平臺上成功通過驗證,此處我們是主要是利用apksigner 工具來驗證APK的簽名是否是屬于正確的開發(fā)者的,apksigner 工具它的位置在[SDK-Path] /build-tools/[版本]。
我們可以使用apksigner工具來驗證 APK的 簽名,apksigner 默認(rèn)安裝位置位于:C:UsersxxxAppDataLocalAndroidSdkuild-tools33.0.0lib下,隨后執(zhí)行如下命令:
$ java -jar C:UsersxxxAppDataLocalAndroidSdkuild-tools33.0.0libapksigner.jar verify --verbose vuls.apk Verifies Verified using v1 scheme (JAR signing): true Verified using v2 scheme (APK Signature Scheme v2): true Verified using v3 scheme (APK Signature Scheme v3): false Verified using v3.1 scheme (APK Signature Scheme v3.1): false Verified using v4 scheme (APK Signature Scheme v4): false Verified for SourceStamp: false Number of signers: 1
當(dāng)然,我們也可以使用 jarsigner 工具來檢查APK的簽名證書的內(nèi)容,但需要注意在調(diào)試證書時,Common Name (CN)屬性要設(shè)置為 "Android Debug"
使用調(diào)試證書簽名的 APK 的輸出,這里我們使用JAVA自帶的jarsigner工具來做簽名,如何簽名的命令如下:
$ jarsigner -verify -verbose -certs vuls.apk sm 14112 Fri Nov 30 00:00:00 CST 1979 AndroidManifest.xml >>> 簽名者 X.509, C=US, O=Android, CN=Android Debug [證書的有效期為18-6-6 下午12:41至48-5-29 下午12:41] [無效的證書鏈: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target]sm 6 Fri Nov 30 00:00:00 CST 1979 META-INF/android.arch.core_runtime.version >>> 簽名者 X.509, C=US, O=Android, CN=Android Debug [證書的有效期為18-6-6 下午12:41至48-5-29 下午12:41] [無效的證書鏈: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target]sm 6 Fri Nov 30 00:00:00 CST 1979 META-INF/android.arch.lifecycle_livedata-core.version (... ...此處省略一堆內(nèi)容) >>> 簽名者 X.509, C=US, O=Android, CN=Android Debug [證書的有效期為18-6-6 下午12:41至48-5-29 下午12:41] [無效的證書鏈: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target] s = 已驗證簽名 m = 在清單中列出條目 k = 在密鑰庫中至少找到了一個證書 i = 在身份作用域內(nèi)至少找到了一個證書- 由 "C=US, O=Android, CN=Android Debug" 簽名 摘要算法: SHA1 (弱) 簽名算法: SHA1withRSA (弱), 1024 位密鑰 (弱)jar 已驗證。 警告: 此 jar 包含其證書鏈無效的條目。原因: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target 此 jar 包含其簽名者證書為自簽名證書的條目。 SHA1 摘要算法被視為存在安全風(fēng)險。此算法將在未來的更新中被禁用。 SHA1withRSA 簽名算法被視為存在安全風(fēng)險。此算法將在未來的更新中被禁用。 RSA 簽名密鑰的密鑰大小 1024 被視為存在安全風(fēng)險。此密鑰大小將在未來的更新中被禁用。 此 jar 包含的簽名沒有時間戳。如果沒有時間戳, 則在其中任一簽名者證書到期 (最早為 2048-05-29) 之后, 用戶可能無法驗證此 jar。 簽名者證書將于 2048-05-29 到期。
上面可以看到出現(xiàn)了許多"CertPath not validated"錯誤,這個錯誤在 Java SDK 7 及以上版本才有,如果想忽略這個錯誤,我們可以使用 Android SDK 構(gòu)建工具的修訂版 24.0.3 及更高版本中提供的 apksigner 工具為 APK 簽名來代替JAVA JDK自帶的 jarsigner 工具來驗證APK的證書鏈,如下:
檢查 APK 的簽名是否可在 APK 支持的所有 Android 平臺上被確認(rèn)為有效:
$ apksigner verify vuls.apk
檢查 APK 的簽名是否可在 Android 4.0.3(API 級別 15)及更高版本上被確認(rèn)為有效:
$ apksigner verify --min-sdk-version 15 vuls.apk
另外簽名配置可以通過Android Studio或build.gradle中的 signingConfig 塊進(jìn)行管理。要同時激活 v1和 v2 以及 v3 方案,必須設(shè)置以下值:
v1SigningEnabled true v2SigningEnabled true v3SigningEnabled true
在官方的 Android 開發(fā)者文檔中,提供了幾種配置應(yīng)用發(fā)布的最佳實踐
Android Studio Signature Version V1/ V2:
V1 (jar Signature)
V1: Jar Signature 來自 JDK,可對簽名后的文件,作適當(dāng)修改,并重新壓縮
V1 簽名不保護(hù) APK 的某些部分,例如 ZIP 元數(shù)據(jù)。APK 驗證程序需要處理大量不可信(尚未經(jīng)過驗證)的數(shù)據(jù)結(jié)構(gòu),然后會舍棄不受簽名保護(hù)的數(shù)據(jù)。這會導(dǎo)致相當(dāng)大的受攻擊面。此外,APK 驗證程序必須解壓所有已壓縮的條目,而這需要花費更多時間和內(nèi)存。為了解決這些問題,Android 7.0 中引入了 APK 簽名方案 v2
V2 (Full APK Signature)
V2: Android 7.0 (Nougat) 引入的一項新的簽名方案,不能對簽名后的 APK作任何修改,包括重新解壓。因為它是針對字節(jié)進(jìn)行的簽名,所以任何改動都會影響最終結(jié)果
V3
V3:在 Android 9 中,v2 方案已更新為 v3 方案(也稱為v2+),以便在簽名分塊中包含其他信息,但在其他方面保持相同的工作方式,該方案會對 APK 的內(nèi)容進(jìn)行哈希處理和簽名,然后將生成的“APK 簽名分塊”插入到 APK 中
APK 簽名方案詳情,請移步Android 官網(wǎng)的介紹
只勾選v1簽名所有機(jī)型都能用,如果只勾選V2簽名7.0以下機(jī)型會在直接安裝完后顯示未安裝,7.0及以上機(jī)型使用V2的方式驗證成功安裝,同時勾選V1和V2對所有機(jī)型成功安裝,或者在Gradle 文件中修改,如下:
signingConfigs { debug { v1SigningEnabled true v2SigningEnabled true v3SigningEnabled true } release { v1SigningEnabled true v2SigningEnabled true v3SigningEnabled true } }
來說說為什么我們要推薦使用v1和v2共同使用呢?因為在2020年的時候Google公布的“Janus”漏洞,可使攻擊者將Dex附加到原有的apk之上,繞過簽名認(rèn)證,在執(zhí)行時優(yōu)先執(zhí)行附加的dex文件,這個漏洞直接影響Android 5.0~8.0上所有基于signature scheme V1簽名的APK。這里說哈,對應(yīng)APK應(yīng)用程序來說簽名確是唯一的,是用來證明是誰開發(fā)的是否是盜版或惡意APK,那么假如正版應(yīng)用被惡意修改,其簽名也會隨之被破壞,需要重新簽名才能安裝到Android上,而且市面上各種APK應(yīng)用商店和手機(jī)應(yīng)用助手類的工具,往往通過包名和簽名來判斷一個APK應(yīng)用程序是否是盜版或惡意APK應(yīng)用程序
注:在官方的 Android 開發(fā)者文檔中,官方提供了幾種配置應(yīng)用發(fā)布的方式,
審核編輯:劉清
-
Android系統(tǒng)
+關(guān)注
關(guān)注
0文章
56瀏覽量
13500 -
API接口
+關(guān)注
關(guān)注
1文章
84瀏覽量
10438 -
apk
+關(guān)注
關(guān)注
0文章
23瀏覽量
4936
原文標(biāo)題:APK應(yīng)用程序是否簽名異常的檢測方法
文章出處:【微信號:哆啦安全,微信公眾號:哆啦安全】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論