android指定簽名的apk才能安裝
最近專案有需求: 只有使用特定簽名籤的apk才可以安裝,其他任何apk都不能安裝(root版,使用adb push進去的除外),以供以後參考。
我們已經知道的是:Android對每一個Apk檔案都會進行簽名,在Apk檔案安裝時,系統會對其簽名信息進行比對,判斷程式的完整性,從而決定該Apk檔案是否可以安裝,在一定程度上達到安全的目的。
給定一個Apk檔案,解壓,可以看到一個META-INFO資料夾,在該資料夾下有三個檔案:分別為MANIFEST.MF、CERT.SF和CERT.RSA。這三個檔案分別表徵以下含義:
(1)MANIFEST.MF:這是摘要檔案。程式遍歷Apk包中的所有檔案(entry),對非資料夾非簽名檔案的檔案,逐個用SHA1生成摘要資訊,再用Base64進行編碼。如果你改變了apk包中的檔案,那麼在apk安裝校驗時,改變後的檔案摘要資訊與MANIFEST.MF的檢驗資訊不同,於是程式就不能成功安裝。
說明:如果攻擊者修改了程式的內容,有重新生成了新的摘要,那麼就可以通過驗證,所以這是一個非常簡單的驗證。
(2)CERT.SF:這是對摘要的簽名檔案。對前一步生成的MANIFEST.MF,使用SHA1-RSA演算法,用開發者的私鑰進行簽名。在安裝時只能使用公鑰才能解密它。解密之後,將它與未加密的摘要資訊(即,MANIFEST.MF檔案)進行對比,如果相符,則表明內容沒有被異常修改。
說明:在這一步,即使開發者修改了程式內容,並生成了新的摘要檔案,但是攻擊者沒有開發者的私鑰,所以不能生成正確的簽名檔案(CERT.SF)。系統在對程式進行驗證的時候,用開發者公鑰對不正確的簽名檔案進行解密,得到的結果和摘要檔案(MANIFEST.MF)對應不起來,所以不能通過檢驗,不能成功安裝檔案。
(3)CERT.RSA檔案中儲存了公鑰、所採用的加密演算法等資訊。
說明:系統對簽名檔案進行解密,所需要的公鑰就是從這個檔案裡取出來的。
結論:從上面的總結可以看出,META-INFO裡面的說那個檔案環環相扣,從而保證Android程式的安全性。(只是防止開發者的程式不被攻擊者修改,如果開發者的公私鑰對對攻擊者得到或者開發者開發出攻擊程式,Android系統都無法檢測出來。)
我們將apk包解包,然後使用命令 keytool -printcert -file CERT.RSA 檢視CERT.RSA,如圖所示:
答案很明顯,CERT.RSA檔案中存放了關於簽名的資訊。
不多說,上修改程式碼:
frameworks/base/services/java/com/android/server/pm/PackageManagerService.java
import java.security.cert.Certificate;
import java.security.MessageDigest;
import java.util.Locale;
// longroey++ start
/**
* Returns the {@link Certificate} fingerprint as returned by <code>keytool</code>.
*
* @param certificate
* @param hashAlgorithm
*/
public static String getFingerprint(Signature signature, String hashAlgorithm) {
if (signature == null) {
return null;
}
try {
MessageDigest digest = MessageDigest.getInstance(hashAlgorithm);
return toHexadecimalString(digest.digest(signature.toByteArray()));
} catch(NoSuchAlgorithmException e) {
// ignore
}
return null;
}
private static String toHexadecimalString(byte[] value) {
StringBuffer sb = new StringBuffer();
int len = value.length;
for (int i = 0; i < len; i++) {
int num = ((int) value[i]) & 0xff;
if (num < 0x10) {
sb.append('0');
}
sb.append(Integer.toHexString(num));
if (i < len - 1) {
sb.append(':');
}
}
return sb.toString().toUpperCase(Locale.US);
}
// longroey++ end
private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
......
try {
pp.collectCertificates(pkg, parseFlags);
pp.collectManifestDigest(pkg);
} catch (PackageParserException e) {
res.setError("Failed collect during installPackageLI", e);
return;
}
// longroey++ start
final String CUSTOMIZED_SIGNATURE = "CF:23:86:90:CB:82:73:F1:B1:F8:F0:44:9E:7A:11:47:67:C3:D5:A2";
final Signature[] mSignatures = pkg.mSignatures;
Slog.d(TAG, "signature fingerprint"
+ getFingerprint(mSignatures[0], "SHA-1"));
if (!getFingerprint(mSignatures[0], "SHA-1").equals(CUSTOMIZED_SIGNATURE)) {
res.setError(PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE,
"Signature verification failed");
return;
}
// longroey++ end
/* If the installer passed in a manifest digest, compare it now. */
if (args.manifestDigest != null) {
if (DEBUG_INSTALL) {
final String parsedManifest = pkg.manifestDigest == null ? "null"
: pkg.manifestDigest.toString();
Slog.d(TAG, "Comparing manifests: " + args.manifestDigest.toString() + " vs. "
+ parsedManifest);
}
if (!args.manifestDigest.equals(pkg.manifestDigest)) {
res.setError(INSTALL_FAILED_PACKAGE_CHANGED, "Manifest digest changed");
return;
}
} else if (DEBUG_INSTALL) {
final String parsedManifest = pkg.manifestDigest == null
? "null" : pkg.manifestDigest.toString();
Slog.d(TAG, "manifestDigest was not present, but parser got: " + parsedManifest);
}
......
}
android簽名的應用-- 禁止未經授權簽名的apk安裝
最近專案有需求: 只有使用特定簽名籤的apk才可以安裝,其他任何apk都不能安裝(root版,使用adb push進去的除外)。n多度娘、google之後最終實現,把實現程式碼羅列一下,以供以後參考.
1、使用工具自己製作簽名檔案,這個簽名就是需要提供給apk製作者簽名使用的。
可以參考原始碼路徑 build/target/product/security/README 檔案
development/tools/make_key testkey ‘/C=CN/ST=ShangHai/L=ShangHai/O=xxx/OU=MTK/CN=China/[email protected]'
2、使用製作好的簽名檔案簽名一個內建的apk,本例採用使用 com.mediatek.factorymode 作為以後簽名的對比物件
mediatek/packages/apps/FactoryMode/Android.mk
增加
- ifeq ($(XHW_SIGNATURE_CONFIG),yes)
- LOCAL_CERTIFICATE := testkey
- endif
3、在安裝過程中對比簽名,如果簽名相同的話就繼續安裝,否則給出一個錯誤號,彈一個訊息框
frameworks/base/services/java/com/android/server/pm/PackageManagerService.java
- private PackageParser.Package scanPackageLI(PackageParser.Package pkg,
- int parseFlags, int scanMode, long currentTime, UserHandle user) {
- ...
- if (!verifySignaturesLP(pkgSetting, pkg)) {
- ...
- }
- //add start
- if(com.mediatek.common.featureoption.FeatureOption.XHW_SIGNATURE_CONFIG) {
- // is xhw signatures
- Signature[] xhwSignatures = getXWHSignatures();
- if (xhwSignatures != null) {
- if (compareSignatures(xhwSignatures, pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
- mLastScanError = PackageManager.INSTALL_FAILED_INVALID_SIGNATURES;
- returnnull;
- }
- }
- }
- //add end
- // Verify that this new package doesn't have any content providers
- // that conflict with existing packages. Only do this if the
- // package isn't already installed, since we don't want to break
- // things that are installed.
- if ((scanMode&SCAN_NEW_INSTALL) != 0) {
- ...
- }
因為在啟動是也要走 scanPackageLI 函式,故增加一個變數 mIsInstallApkFlag 判斷是否是安裝過程
- privatevoid installPackageLI(InstallArgs args,
- boolean newInstall, PackageInstalledInfo res) {
- ...
- Log.i(TAG, "Start installation for package: " + pkg.packageName);
- //add start
- if(com.mediatek.common.featureoption.FeatureOption.XHW_SIGNATURE_CONFIG) {
- Log.i(TAG, "installPackageLI-111- mIsInstallApkFlag="+mIsInstallApkFlag);
- mIsInstallApkFlag = true;
- Log.i(TAG, "installPackageLI-222- mIsInstallApkFlag="+mIsInstallApkFlag);
- }
- //add end
- if (replace) {
- replacePackageLI(pkg, parseFlags, scanMode, args.user,
- installerPackageName, res);
- } else {
- installNewPackageLI(pkg, parseFlags, scanMode, args.user,
- installerPackageName, res);
- }
- Log.i(TAG, "Installation done for package: " + pkg.packageName);
- ...
- }
增加的函式為:
- //add start
- privateboolean mIsInstallApkFlag = false;
- private Signature[] getXWHSignatures(){
- if(!mIsInstallApkFlag) returnnull;
- // 取得xhw簽名
- Signature[] xhwSigns = null;
- String packageName = "com.mediatek.factorymode";
- /* try {
- //PackageInfo xhwPackageInfo = mContext.getPackageManager().getPackageInfo("com.mediatek.factorymode", PackageManager.GET_SIGNATURES); //-- 只能取得已安裝的apk 簽名
- PackageInfo xhwPackageInfo = getPackageInfo("com.mediatek.factorymode", PackageManager.GET_SIGNATURES, Process.SYSTEM_UID);
- if(xhwPackageInfo != null){
- xhwSigns = xhwPackageInfo.signatures;
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- if(xhwSigns != null) Log.e(TAG, "....----getXWHSignatures--xhw_Signs[0]="+xhwSigns[0].toCharsString());
- */
- //another method
- PackageSetting ps = mSettings.mPackages.get(packageName);
- if (ps != null) {
- PackageParser.Package pkg = ps.pkg;
- if (pkg == null) {
- pkg = new PackageParser.Package(packageName);
- pkg.applicationInfo.packageName = packageName;
- pkg.applicationInfo.flags = ps.pkgFlags | ApplicationInfo.FLAG_IS_DATA_ONLY;
- pkg.applicationInfo.publicSourceDir = ps.resourcePathString;
- pkg.applicationInfo.sourceDir = ps.codePathString;
- pkg.applicationInfo.dataDir = getDataPathForPackage(packageName, 0).getPath();
- pkg.applicationInfo.nativeLibraryDir = ps.nativeLibraryPathString;
- }
- PackageInfo xhwPackageInfo2 = generatePackageInfo(pkg, PackageManager.GET_SIGNATURES, UserHandle.getCallingUserId());
- if(xhwPackageInfo2 != null){
- xhwSigns = xhwPackageInfo2.signatures;
- }
- }
- // reset flag
- mIsInstallApkFlag = false;
-
相關推薦
android指定簽名的apk才能安裝
最近專案有需求: 只有使用特定簽名籤的apk才可以安裝,其他任何apk都不能安裝(root版,使用adb push進去的除外),以供以後參考。 我們已經知道的是:Android對每一個Apk檔案都會進行簽名,在Apk檔案安裝時,系統會對其簽名信息進行比對
Android原始碼筆記--APK解除安裝過程
Android中應用的解除安裝主要是通過PackageManager中提供的deletePackage()函式來解除安裝,該函式通過IPC呼叫到Pms的deletePackage()函式,繼而呼叫到deletePac
Android studio簽名打包後安裝出現解析包有問題
用Android studio簽名打包後安裝在一些手機上解析包出現問題,因為不涉及網路從伺服器下載安裝包,所以很大情況是由於手機系統版本過低造成。基於此,as開發預設會使用最新的SDK,所以要修改一下安裝在裝置最低版本,在build.gradle檔案中修改,一般
解決android studio 簽名打包後安裝失敗的問題
剛開始學簽名打包,按照教程點選開啟連線一步步的做下去,過程蠻簡單的,結果最後一步出現了一個錯誤上圖 這個錯誤可以讓我崩潰,因為花了我一上午的時間去解決言歸正傳1.首先檢視minS
android 內建apk 解除安裝後開機自動恢復的實現
最近刷了個ROM 發現裡面有幾個內建APK,在 /system/app/ 我用 RE管理器刪除後,重新開機,莫名其妙有恢復了 我擦,按照我目前對安卓系統的瞭解,我才應該是某個開機啟動程式,在開機的時候釋放,於是我苦苦搜尋此程式未果 於是我想,android 基於 lin
Android 生成簽名apk與多渠道打包
一、生成簽名apk 之前我們都是通過Android Studio來將程式安裝到手機上的,而它背後實際的工作流程是Android Studio會將程式程式碼打包成一個APK檔案,然後將這個檔案傳送到手
android jarsigner 簽名apk簡單使用說明
jarsigner構成解析: jarsigner -verbose -keystore 簽名包路徑-signedjar apk簽名之後存放路徑 未簽名的apk檔案路徑 簽名包的別稱 舉例: jarsigner -verbose -keystore D:\test\juesK
Android Studio 2.3 以後給apk簽名打包後安裝失敗的問題
本人java小白,最近一直在學習java,然後接觸到AS,apk簽名打包完成並顯示打包成功(具體簽名步驟看Android Studio 程式簽名打包),在驗證簽名打包是否真的成功,發現結果顯示沒有簽名。如下圖: 谷歌搜尋了一些解決方法,發現 官網上的解釋: 標紅的地方已經提到
android studio生成簽名apk後在手機上安裝不了
我的應用在debug時可以正常執行,但是生成簽名apk後放到手機裡總是安裝失敗。 原因1:在Build選單下點選Select Build Variant彈出對話方塊後,看看你的Module的Build Variant是否是release,是debug的話改為release。
android studio 簽名遇到的坑(apk無法安裝,安裝後閃退)
今天需要拿出一個版本提測,打包好以後發給測試,測試反饋安裝上以後無法開啟,一開啟就閃退。 在網上找了些資料,也有遇到同樣問題的小夥伴,在此學習總結一下; 1.android studio 打包簽名後無法安裝到手機,總是安裝失敗。這時可能是在打包的時候沒有勾選圖中兩個。 2
Android給已生成的安裝包apk用自己的keystore檔案簽名
一、用cmd命令指定到自己安裝的jdk的bin目錄下 快捷鍵開始選單鍵+R進入圖一介面,輸入cmd,進入命令視窗, 二、準備好你自己的keystore檔案的,複製你的keys
android studio2.3以後給apk簽名打包後安裝失敗的問題[INSTALL_PARSE_FAILED_NO_CERTIFICATES]
自己的Android studio(windows平臺上)剛剛更新到2.3版本,在沒有充分了解它的新變化的情況下,使用的時候難免會遇到一些問題,比如gradle的問題可能是大家最常見的,不過解決的一般思路和之前(例如2.1更新到2.2之類的)沒太大區別,本文要說不是gra
有的系統區apk需要對其系統簽名,才能正常使用。
tput 簽名 系統簽名 pem nap ava idp uil 兩個文件 韓夢飛沙 韓亞飛 [email protected]/* */ yue31313 han_meng_fei_sha 向方案公司索要platform.x509.pem 和plat
Android 檢查手機上是否安裝了指定的軟件(根據包名檢測)
gem ++ info add 包名 boolean nta avi ray Android檢查手機上是否安裝了指定的軟件(根據包名檢測) /** * 檢查手機上是否安裝了指定的軟件 * @param context * @param packageName
android v2簽名、渠道包安裝失敗
android 7.0開始增加了v2簽名,能夠加速app的安裝結束。 v2簽名機制:v2是android 7.0開始引入,使用SHA256雜湊值校驗,會對每個檔案的二進位制位元組進行校驗,對應用提供更安全的保護,不管簽名後對檔案做了任何修改,都會導致在android 7.0以上的機型安裝失敗
android 下載apk後安裝apk(適配android 7.0)
為適配7.0以後系統,首先需要在AndroidManifest.xml檔案中application節點下定義provider,如下: <provider android:nam
通過Android studio生成apk安裝失敗
自己寫了個東西虛擬機器除錯通過,想在手機測試一下,找到apk檔案,傳到手機發現如圖所示-_-||。 我日這什麼情況 讓後百度,谷歌 ---------------------------------------------------------------------
具有系統簽名的APK實現APK靜默安裝
針對具有系統簽名許可權的APK(系統運用)要實現對其它第三方APK靜默安裝可用如下程式碼實現 1、manifest中許可權申請 <uses-permission android:name="android.permission.INSTALL_PACKAGES" />
unity+android:大版本更新安裝下好的apk,相容任意安卓5.0,7.0,8.0版本
Android Studio 1:在專案的res目錄下建立xml目錄,再建立file_paths.xml檔案。 <?xml version="1.0" encoding="utf-8"?> <paths> <root-pa
android APK應用安裝解除安裝
一:APK安裝解除安裝路徑及方式 APK是類似Symbian Sis或Sisx的檔案格式。通過將APK檔案直接傳到Android模擬器或Android手機中執行即可安裝。 1· Android應用安裝方式 1. 系統應用安裝――開機時完成,沒有安裝介面 2. 網路下載應用安裝